明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 820|回复: 4

文本盒三种方式获取

  [复制链接]
发表于 2025-3-13 18:31:24 | 显示全部楼层 |阅读模式
本帖最后由 gzxl 于 2025-3-13 18:33 编辑

文本盒(好像三种方式)获取,总结 getGeomExtents 比较其他两者范围大些,acedTextBox 和 AcGiTextStyle 差不多。



getGeomExtents 方式
  1. ads_name eName;
  2. ads_point pt;
  3. if (RTNORM != acedEntSel(_T("\n选择一个单行文字画包围盒:"), eName, pt))
  4.     return;
  5. AcDbObjectId objId;
  6. acdbGetObjectId(objId, eName);
  7. AcDbText* pText;
  8. acdbOpenObject(pText, objId, AcDb::kForRead);
  9. if (objId == NULL)
  10.     return;

  11. AcDbExtents ext;
  12. pText->getGeomExtents(ext);
  13. AcGePoint2d minPt, maxPt; // 左下角 右上角
  14. minPt[X] = ext.minPoint().x;
  15. minPt[Y] = ext.minPoint().y;
  16. maxPt[X] = ext.maxPoint().x;
  17. maxPt[Y] = ext.maxPoint().y;
  18. pText->close();

  19. // 左上角 右下角
  20. AcGePoint2d ptLeftTop(minPt.x, maxPt.y);
  21. AcGePoint2d ptRightBottom(maxPt.x, minPt.y);
  22. AcDbPolyline *pPoly = new AcDbPolyline(4);
  23. pPoly->addVertexAt(0, minPt, 0, 0, 0);
  24. pPoly->addVertexAt(1, ptRightBottom, 0, 0, 0);
  25. pPoly->addVertexAt(2, maxPt, 0, 0, 0);
  26. pPoly->addVertexAt(3, ptLeftTop, 0, 0, 0);
  27. pPoly->setClosed(Adesk::kTrue);

  28. AcDbBlockTable* pBlockTable;
  29. acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
  30. AcDbBlockTableRecord* pBlockTableRecord;
  31. pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
  32. AcDbObjectId polyId;
  33. pBlockTableRecord->appendAcDbEntity(polyId, pPoly);
  34. pBlockTable->close();
  35. pBlockTableRecord->close();
  36. pPoly->close();
复制代码
acedTextBox 方式
  1. // 结果缓冲区列表中搜索指定类型的组码
  2. static struct resbuf* EntItem(struct resbuf *rchain, int gcode)
  3. {
  4. while ((rchain != NULL) && (rchain->restype != gcode))
  5.     rchain = rchain->rbnext;
  6. return rchain;
  7. }

  8. ads_name tname;
  9. struct resbuf *textent, *tent;
  10. ads_point origin, lowleft, upright, p1, p2, p3, p4;
  11. ads_real rotatn;
  12. TCHAR rotatstr[15];
  13. if (acedEntSel(_T("\n选择一个单行文字画包围盒: "), tname, p1) != RTNORM)
  14. {
  15.     acdbFail(_T("没有选择文本实体\n"));
  16.     return;
  17. }
  18. textent = acdbEntGet(tname);
  19. if (textent == NULL)
  20. {
  21.     acdbFail(_T("无法检索文本实体\n"));
  22.     return;
  23. }
  24. tent = EntItem(textent, 10);
  25. origin[X] = tent->resval.rpoint[X]; // ECS 坐标
  26. origin[Y] = tent->resval.rpoint[Y];
  27. tent = EntItem(textent, 50);
  28. rotatn = tent->resval.rreal;
  29. // acdbAngToS() 将弧度转换为度数
  30. if (acdbAngToS(rotatn, 0, 8, rotatstr) != RTNORM)
  31. {
  32.     acdbFail(_T("弧度转换为度数失败!\n"));
  33.     acutRelRb(textent);
  34.     return;
  35. }
  36. if (acedTextBox(textent, lowleft, upright) != RTNORM)
  37. {
  38.     acdbFail(_T("无法检索文本框坐标\n"));
  39.     acutRelRb(textent);
  40.     return;
  41. }
  42. acutRelRb(textent);
  43. // 如果当前不在 WCS 中,此时添加
  44. // 调用 acedTrans() 转换坐标
  45. // 从 acedTextBox() 中检索
  46. p1[X] = origin[X] + lowleft[X]; // UCS 坐标
  47. p1[Y] = origin[Y] + lowleft[Y];
  48. p2[X] = origin[X] + upright[X];
  49. p2[Y] = origin[Y] + lowleft[Y];
  50. p3[X] = origin[X] + upright[X];
  51. p3[Y] = origin[Y] + upright[Y];
  52. p4[X] = origin[X] + lowleft[X];
  53. p4[Y] = origin[Y] + upright[Y];

  54. AcGePoint2d pt1, pt2, pt3, pt4;
  55. pt1[X] = p1[X];
  56. pt1[Y] = p1[Y];
  57. pt2[X] = p2[X];
  58. pt2[Y] = p2[Y];
  59. pt3[X] = p3[X];
  60. pt3[Y] = p3[Y];
  61. pt4[X] = p4[X];
  62. pt4[Y] = p4[Y];

  63. AcDbPolyline *pPoly = new AcDbPolyline(4);
  64. pPoly->addVertexAt(0, pt1, 0, 0, 0);
  65. pPoly->addVertexAt(1, pt2, 0, 0, 0);
  66. pPoly->addVertexAt(2, pt3, 0, 0, 0);
  67. pPoly->addVertexAt(3, pt4, 0, 0, 0);
  68. pPoly->setClosed(Adesk::kTrue);

  69. AcDbBlockTable* pBlockTable;
  70. acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
  71. AcDbBlockTableRecord* pBlockTableRecord;
  72. pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
  73. AcDbObjectId polyId;
  74. pBlockTableRecord->appendAcDbEntity(polyId, pPoly);
  75. pBlockTable->close();
  76. pBlockTableRecord->close();
  77. pPoly->close();

  78. AcGePoint3d ptBase;
  79. ptBase.x = origin[X];
  80. ptBase.y = origin[Y];
  81. ptBase.z = 0.0;

  82. AcGeMatrix3d xform;
  83. AcGeVector3d vec(0, 0, 1);
  84. xform.setToRotation(rotatn, vec, ptBase);
  85. AcDbEntity *pEnt = NULL;
  86. Acad::ErrorStatus es = acdbOpenObject(pEnt, polyId, AcDb::kForWrite, false);
  87. if (es == Acad::eOk)
  88. {
  89.     es = pEnt->transformBy(xform);
  90.     pEnt->close();
  91. }
复制代码

AcGiTextStyle 方式
  1. Acad::ErrorStatus es = Acad::eOk;
  2. AcGiTextStyle textStyle;
  3. AcDbTextStyleTable* pTable = NULL;
  4. AcDbTextStyleTableRecord* pRecord = NULL;
  5. acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pTable, AcDb::kForRead);
  6. const ACHAR* styleName = strFontName;
  7. es = pTable->getAt(styleName, pRecord, AcDb::kForRead);
  8. if (es == Acad::eOk)
  9. {
  10.     fromAcDbTextStyle(textStyle, pRecord->objectId());
  11.     pRecord->close();
  12.     pTable->close();
  13.     textStyle.loadStyleRec();
  14.     textStyle.extentsBox(str, Adesk::kFalse, _tcslen(str), Adesk::kTrue, extMin, extMax);
  15. }
复制代码








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1明经币 +1 收起 理由
cable2004 + 1 很给力!

查看全部评分

回复

使用道具 举报

发表于 2025-3-13 19:46:01 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

发表于 2025-3-13 20:16:28 | 显示全部楼层
我还以为有解析字体文件了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-3-15 12:06:49 | 显示全部楼层
AcGiTextStyle 方式没写全,补一下。

  1.     // AcGiTextStyle 方式
  2.     static void GetTextStrBox(LPCTSTR str, const CString& strFontName, AcGePoint2d& extMin, AcGePoint2d& extMax)
  3.     {
  4.         Acad::ErrorStatus es = Acad::eOk;
  5.         AcGiTextStyle textStyle;
  6.         AcDbTextStyleTable* pTable = NULL;
  7.         AcDbTextStyleTableRecord* pRecord = NULL;
  8.         acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pTable, AcDb::kForRead);
  9.         const ACHAR* styleName = strFontName;
  10.         es = pTable->getAt(styleName, pRecord, AcDb::kForRead);
  11.         if (es == Acad::eOk)
  12.         {
  13.             fromAcDbTextStyle(textStyle, pRecord->objectId());
  14.             pRecord->close();
  15.             pTable->close();
  16.             textStyle.loadStyleRec();
  17.             textStyle.extentsBox(str, Adesk::kFalse, _tcslen(str), Adesk::kTrue, extMin, extMax);
  18.         }
  19.     }

  20.         ads_name eName;
  21.         ads_point pt;
  22.         if (RTNORM != acedEntSel(_T("\n选择一个单行文字画包围盒:"), eName, pt))
  23.             return;
  24.         AcDbObjectId objId;
  25.         acdbGetObjectId(objId, eName);
  26.         AcDbText* pText = NULL;
  27.         acdbOpenObject(pText, objId, AcDb::kForRead);
  28.         if (objId == AcDbObjectId::kNull)
  29.             return;
  30.         ACHAR* acText = pText->textString();
  31.         CString strText = acText;
  32.         delete[]acText;
  33.         AcDbObjectId textStyleId = pText->textStyle();
  34.         AcDbTextStyleTableRecord* pTextStyleRcd = NULL;
  35.         if (acdbOpenObject(pTextStyleRcd, textStyleId, AcDb::kForRead) == Acad::eOk)
  36.         {
  37.             ACHAR* textStyleName;
  38.             pTextStyleRcd->getName(textStyleName);
  39.             CString strFontName(textStyleName);
  40.             pTextStyleRcd->close();
  41.             delete[]textStyleName;
  42.             // 使用 AcGiTextStyle 查找文本字符串的范围
  43.             AcGePoint2d extMin, extMax;
  44.             GetTextStrBox(strText, strFontName, extMin, extMax);
  45.             // 范围点赋值给 pt1 pt2
  46.             AcGePoint3d pt1(extMin.x, extMin.y, 0.0);
  47.             AcGePoint3d pt2(extMax.x, extMax.y, 0.0);
  48.             // 3D 空间的仿射变换
  49.             AcGeMatrix3d coordSysMat;
  50.             // 返回与文本平面法线向量正交的向量(法线向量 WCS 坐标)
  51.             AcGeVector3d xAxis = pText->normal().perpVector();
  52.             // 返回文本平面法线向量的叉积
  53.             AcGeVector3d yAxis = pText->normal().crossProduct(xAxis);
  54.             // 输入角度围绕输入点旋转实体
  55.             xAxis.rotateBy(pText->rotation(), pText->normal());
  56.             yAxis.rotateBy(pText->rotation(), pText->normal());
  57.             // 设置矩阵
  58.             coordSysMat.setCoordSystem(pText->position(), xAxis, yAxis, pText->normal());
  59.             // 应用变换矩阵
  60.             pt1.transformBy(coordSysMat);
  61.             pt2.transformBy(coordSysMat);
  62.             // 提取两个角点的坐标值
  63.             double x1 = pt1.x, x2 = pt2.x;
  64.             double y1 = pt1.y, y2 = pt2.y;
  65.             // 计算矩形的角点
  66.             AcGePoint2d ptLeftBottom(min(x1, x2), min(y1, y2));
  67.             AcGePoint2d ptRightBottom(max(x1, x2), min(y1, y2));
  68.             AcGePoint2d ptRightTop(max(x1, x2), max(y1, y2));
  69.             AcGePoint2d ptLeftTop(min(x1, x2), max(y1, y2));
  70.             // 创建多段线
  71.             AcDbPolyline* pPoly = new AcDbPolyline(4);
  72.             pPoly->addVertexAt(0, ptLeftBottom, 0, 0, 0); // 添加顶点
  73.             pPoly->addVertexAt(1, ptRightBottom, 0, 0, 0);
  74.             pPoly->addVertexAt(2, ptRightTop, 0, 0, 0);
  75.             pPoly->addVertexAt(3, ptLeftTop, 0, 0, 0);
  76.             pPoly->setClosed(Adesk::kTrue); // 设置闭合
  77.             // 获得当前图形数据库的块表
  78.             AcDbBlockTable* pBlockTable = NULL;
  79.             acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
  80.             // 获得模型空间对应的块表记录
  81.             AcDbBlockTableRecord* pBlockTableRecord = NULL;
  82.             pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
  83.             // 将多段线实体添加到模型空间的块表记录
  84.             AcDbObjectId polyId;
  85.             pBlockTableRecord->appendAcDbEntity(polyId, pPoly);
  86.             // 关闭模型空间块表记录和多段线实体
  87.             pBlockTable->close();
  88.             pBlockTableRecord->close();
  89.             pPoly->close();
  90.         }
  91.         pText->close();
复制代码


回复 支持 反对

使用道具 举报

发表于 2025-3-15 16:53:48 | 显示全部楼层

谢谢楼主分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-4-1 09:25 , Processed in 0.983904 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表