使用KOMPAS-3D API→第13课→段落

在继续使用记录的方法来创建复合字符串之前,我们需要熟悉一个对象(例如段落)。 它是由几行组成的自动格式化的文本块。 在本课程中,我们将研究构建简单的段落。



课程系列“使用KOMPAS-3D API的工作”的内容


  1. 基础知识
  2. 图纸设计
  3. 正确连接到KOMPAS
  4. 主题词
  5. 图形图元
  6. 以各种格式保存文档
  7. 了解设置
  8. 标题栏中更复杂的书写方法
  9. 读取字幕单元
  10. 特殊字符,包括字符串
  11. 简单文字标签
  12. 复合弦
  13. 段落
  14. 多行文字

段落参数( ksParagraphParam


ksParagraphParam接口描述了一个段落。 要获取它,您需要使用KompasObject接口的GetParamStruct方法,为此您需要将常量ko_ParagraphParam0x0000001B )传递给它。 考虑ksParagraphParam接口的属性。

ang-文本的角度,以度为单位。 它从水平线逆时针延迟。 类似于ksText方法的ang参数。

height-段落的高度,以毫米为单位。

hFormat-水平格式化文本。 当文本的宽度不适合段落宽度时,使用此属性。 有效值在下表中列出。



style-文本样式(在第11节中进行了介绍 )。

vFormat-垂直格式化文本。 当文本不适合段落的高度时,使用此属性。 有效值在下表中列出。



使用vFormat属性时,要记住两件事

  1. 根据KOMPAS文档, vFormat属性的有效值为0-1 ,但事实并非如此。 有效值为01
  2. COMPASS不会更改字符的高度。 它仅更改线之间的距离。 如果线条的高度小于段落的高度,则它们可以重叠。 下图是此类叠加层的示例。



width-段落的宽度,以毫米为单位。
属性heighthFormatvFormatwidth允许我们解决将文本放置在给定矩形中的问题。 该方法比第11课中讨论的ksGetTextLength方法更加可靠和高效。

xy是锚点的坐标。 段落相对于锚点沿水平轴的位置由ksDocument2D接口的ksSetTextAlign方法调整(尽管未记录这种可能性)。 垂直锚点始终与段落第一行的底部匹配。 此行为无法更改。
ksParagraphParam接口只有一种方法: Init() 。 它初始化接口的属性值。 没有输入参数。 如果成功,则返回true

段落建设


创建一个段落包含三个连续步骤。

  1. 本段开头的声明。 为此, 调用 ksDocument2D接口的ksParagraph方法。 作为唯一参数,此方法接受ksParagraphParam接口,该接口设置段落的参数。 如果成功,则ksParagraph方法返回1,如果发生错误,则返回0
  2. 填充段落。 对于段落中显示的每一行,都会调用 ksDocument2D接口的ksTextLine方法。 作为唯一参数,它接受描述字符串的ksTextItemParamksTextLineParam接口 (在循环的上一课中讨论过)。 请注意,输出行不得包含@$^字符,因为它们是控制字符。 在本周期的下一课中将考虑与他们合作。
  3. 段末。 为此, 调用 ksDocument2D接口的ksEndObj()方法。 它没有输入参数,如果成功,则返回指向创建的对象(段落)的整数指针。 如果发生错误,它将返回

一个例子。 最简单的段落


下面是该程序的源代码,演示了一个简单段落的构造。
//  ksTextItemParam TextItemParamPtr textItemParam; textItemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); //    ParagraphParamPtr paragraphParam; paragraphParam = static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(100.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); //  BSTR str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); //  Document2D->ksEndObj(); paragraphParam.Unbind(); textItemParam.Unbind(); 


与往常一样,这里为了简单起见,省略了负责创建和执行文档的代码(在上一课程中讨论了该主题)。

在此示例中,KOMPAS本身根据其内容确定段落的大小。 下图显示了生成的段落。



请注意:文本显示为一行。 我们没有指定段落的宽度,因此KOMPAS会根据需要自动将其增加。 如果设置了宽度,则COMPASS行为将由ksParagraphParam接口的hFormat属性的值确定。

要形成多行和复合文本,您需要使用上一课中部分讨论的图形功能。

一个例子。 多行文字


要显式行,请使用NEW_LINE标志( 0x1000 )。

下面是一个示例程序,演示了使用此标志构建多行段落。
 //  ksTextItemParam TextItemParamPtr textItemParam; textItemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); //    ParagraphParamPtr paragraphParam; paragraphParam = static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(100.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); //  BSTR str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); TextItemFontPtr textItemFont; textItemFont = static_cast<TextItemFontPtr>(textItemParam->GetItemFont()); textItemFont->SetBitVectorValue(NEW_LINE, true); str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); textItemFont.Unbind(); str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); //  Document2D->ksEndObj(); paragraphParam.Unbind(); textItemParam.Unbind(); 


在本示例中,将创建一个三行段落。 第一行照常显示。 第二,设置NEW_LINE标志。 他谈到新生产线的开始。 第三行照常显示,但是NEW_LINE标志仍处于活动状态,因为我们正在使用ksTextItemParam接口的相同实例。 下图显示了此程序生成的段落。


现在,这些行已正确显示。

使用段落的挑战


文字对齐


文本对齐方式是通过ksDocument2D接口的ksSetTextLineAlign方法设置的。 它只有一个整数参数-设置对齐方式。 下表列出了其有效值。



如果成功,则ksSetTextLineAlign方法将返回上一个对齐标记,如果发生错误,则返回-1

请注意, ksSetTextLineAlign方法只能在块内使用(在我们的示例中,它在段落内使用)。 这意味着它不能用于设置ksText方法输出的文本的对齐方式。 这种限制是由于这样的事实,在这种情况下,KOMPAS不知道需要对齐哪个边框。
另一个要点与ksSetTextLineAlign方法的范围有关-它影响输出的行。 考虑一个示例(与原始示例相比,此处使用了非常简化的语法):

 ksSetTextLineAlign(1); ksTextLine(“ ”); ksSetTextLineAlign(2); ksTextLine(“  ”); 

线条将如何对齐? 与我们的预期相反,两条线将向右对齐。 怎么了 事实是, ksSetTextLineAlign方法首先会更改最后一条输出线的对齐方式。 这是我们示例中发生的情况:第一行​​设置中心对齐。 由于没有先前的输出行,因此此调用将更改默认对齐方式(左)。

然后我们打印“中心”行。 最初,它使用先前的中心对齐设置。

在第三行中,我们再次更改对齐方式。 首先,该方法更改前一行(“中心”)的对齐方式。 因此,它按照我们的计划在右侧而不是在中心对齐。 默认情况下,相同的对齐方式将对齐。
我们显示“右”行。 由于不再调用ksSetTextLineAlign方法,因此它使用先前设置的对齐方式(在右侧)。
因此,两条线都向右对齐。 现在让我们稍微更改一下示例:

 ksSetTextLineAlign(1); ksTextLine(“ ”); ksTextLine(“”); ksSetTextLineAlign(2); ksTextLine(“  ”); 

我们所做的只是在不更改对齐方式的情况下添加空字符串的输出。 现在,这些行已正确显示。 这是因为空字符串的输出“吸收”了设置的右对齐。 对ksSetTextLineAlign方法的第二次调用会影响空行,并且不会以任何方式影响中心线。
下面的示例显示正确的对齐方式,而不显示空字符串。

 ksTextLine(“ ”); ksSetTextLineAlign(1); ksTextLine(“  ”); ksSetTextLineAlign(2); 

调用ksTextLineksSetTextLineAlign被交换。 由于ksSetTextLineAlign方法主要影响最后显示的行,因此正确设置了对齐方式,并根据需要显示了行。

例子


以下是演示段落中文本对齐方式的程序的源代码。
 //  ksTextItemParam TextItemParamPtr textItemParam; textItemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); //    ParagraphParamPtr paragraphParam; paragraphParam = static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(100.0); paragraphParam->set_y(100.0); paragraphParam->set_width(60.0); paragraphParam->set_hFormat(2); //  Document2D->ksParagraph(paragraphParam); //  BSTR str = SysAllocString(L"    "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); TextItemFontPtr textItemFont; textItemFont = static_cast<TextItemFontPtr>(textItemParam->GetItemFont()); textItemFont->SetBitVectorValue(NEW_LINE, true); str = SysAllocString(L""); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); textItemFont.Unbind(); str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); Document2D->ksSetTextLineAlign(1); str = SysAllocString(L""); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); str = SysAllocString(L"    "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); Document2D->ksSetTextLineAlign(3); //  Document2D->ksEndObj(); paragraphParam.Unbind(); textItemParam.Unbind(); 


在此示例中,除了文本对齐方式以外,还演示了ksParagraphParam接口的widthhFormat属性的使用。 它们用于限制其宽度。 如果我们不更改它们,KOMPAS将增加该段落的宽度,并且看不到左侧和宽度的对齐方式。

显示空白行以提高段落的可读性。 它们不会影响正确的对齐方式。

下图显示了此程序生成的段落。



打开或关闭样式


在本周期第11课中,我们检查了控制样式的标志( ITALIC_ONITALIC_OFFBOLD_ONUNDERLINE_ONUNDERLINE_OFF )。 然后,我们针对ksText方法检查了它们。 它们在段落中的应用之间的重要区别是,该操作不仅限于调用ksTextLine方法,还可以扩展到整个段落。 让我们看几个例子。

 TextItemFont->SetBitVectorValue(BOLD_ON, true); TextItemParam->s = SysAllocString(L” ”); Document2D->ksTextLine(TextItemParam); TextItemFont->Init(); TextItemParam->s = SysAllocString(L” ”); Document2D->ksTextLine(TextItemParam); 

第一行将以粗体显示。 毫无疑问。 但是第二行将如何显示? 标志BOLD_ON已为她重置。 因此,我们可以假定它将以常规字体显示。 但是事实并非如此。 遇到BOLD_ON标志后,KOMPAS将按以下方式理解命令:该段的所有后续行均以粗体显示。 因此,所有后续行均以粗体显示,直到该段落完成或COMPASS不会遇到与其配对BOLD_OFF标志。 考虑一个例子:

 TextItemFont.SetBitVectorValue(BOLD_ON, true); TextItemParam.s = SysAllocString(L” ”); Document2D.ksTextLine(TextItemParam); TextItemFont.Init(); TextItemFont.SetBitVectorValue(BOLD_OFF, true); TextItemParam.s = SysAllocString(L“ ”); Document2D.ksTextLine(TextItemParam); TextItemFont.Init(); TextItemParam.s = SysAllocString(L” ”); Document2D.ksTextLine(TextItemParam); 

第一行以粗体显示。 对于第二行,我们清除BOLD_ON标志,并将与之配对的BOLD_OFF标志终止,这将取消粗体样式。 因此,第二和第三行显示为不加粗。

此行为适用于标志ITALIC_ONITALIC_OFFUNDERLINE_ONUNDERLINE_OFF ,但不适用于NEW_LINE标志,因为它没有一对覆盖标志。

例子


以下是程序的源代码,使用段落显示了不同样式的文本输出。
 //  ksTextItemParam TextItemParamPtr textItemParam; textItemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); //    ParagraphParamPtr paragraphParam; paragraphParam = static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(100.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); //  BSTR str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); TextItemFontPtr textItemFont; textItemFont = static_cast<TextItemFontPtr>(textItemParam->GetItemFont()); textItemFont->set_bitVector(NEW_LINE | ITALIC_OFF); // str = SysAllocString(L"  "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); textItemFont->set_bitVector(NEW_LINE | ITALIC_ON | BOLD_ON); // str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); textItemFont->set_bitVector(NEW_LINE | BOLD_OFF | UNDERLINE_ON); // str = SysAllocString(L" "); textItemParam->set_s(str); Document2D->ksTextLine(textItemParam); SysFreeString(str); //  Document2D->ksEndObj(); paragraphParam.Unbind(); textItemFont.Unbind(); textItemParam.Unbind(); 


该程序最重要的部分是正确设置输出线的标志。 让我们更详细地分析它(程序的相应行用一对字符“ // ”标记)。

显示的第一行没有任何更改。 因此,没有为其设置标志。

第二行应显示为没有斜率,并以新行显示。 因此,将为其设置标志: NEW_LINE (从新行开始)和ITALIC_OFF (禁用斜体 )。

第三行应以斜体和粗体显示。 为此,我们将标记设置为: NEW_LINEITALIC_ON启用斜体)和BOLD_ON启用粗体)。 所有其他标志均被重置。

第四行应以斜体显示,带下划线,而不要加粗。 为此,我们对以下标志进行翘起: NEW_LINEBOLD_OFF (禁用粗体,从上一行开始保留)和UNDERLINE_ON (启用带下划线的)。

如果段落中有更多行,它们将以斜体带下划线的字体显示。 要禁用带下划线的样式,必须清除UNDERLINE_ON标志,并旋开UNDERLINE_OFF标志。

下图显示了该程序的结果。



从演示中分离信息


如果遵循程序的结构,您可能会注意到上一个示例的严重缺陷:负责生成输出的代码与负责实现其输出的代码混合在一起。 具有良好的编程风格,习惯上将信息与其表示分开。

如果输出信息由几行ksTextItemParam组成 ,则可以将它们组合到一个接口ksTextLineParam中ksTextLine方法可以处理这两个接口。 但是这种方法有一个令人不愉快的局限性:如果ksTextLine方法接受ksTextLineParam接口,则将忽略NEW_LINE (和SPECIAL_SYMBOL_END )标志。 也就是说,即使为某些ksTextItemParam 实例设置NEW_LINE标志,所有信息也将显示在一行上。 要变通解决此限制,您必须为每行手动调用ksTextLine

以下是演示此技术的示例的源代码。
 //    DynamicArrayPtr dynamicArray; dynamicArray = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_ITEM_ARR)); dynamicArray->ksClearArray(); //  ksTextItemParam TextItemParamPtr textItemParam; textItemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); //   BSTR str = SysAllocString(L" "); textItemParam->set_s(str); dynamicArray->ksAddArrayItem(-1, textItemParam); SysFreeString(str); TextItemFontPtr textItemFont; textItemFont = static_cast<TextItemFontPtr>(textItemParam->GetItemFont()); textItemFont->set_bitVector(NEW_LINE | ITALIC_OFF); str = SysAllocString(L"  "); textItemParam->set_s(str); dynamicArray->ksAddArrayItem(-1, textItemParam); SysFreeString(str); textItemFont->set_bitVector(NEW_LINE | ITALIC_ON | BOLD_ON); str = SysAllocString(L" "); textItemParam->set_s(str); dynamicArray->ksAddArrayItem(-1, textItemParam); SysFreeString(str); textItemFont->set_bitVector(NEW_LINE | BOLD_OFF | UNDERLINE_ON); str = SysAllocString(L" "); textItemParam->set_s(str); dynamicArray->ksAddArrayItem(-1, textItemParam); SysFreeString(str); //    ParagraphParamPtr paragraphParam; paragraphParam = static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(100.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); //     for(unsigned int i = 0; i < dynamicArray->ksGetArrayCount(); ++i) { dynamicArray->ksGetArrayItem(i, textItemParam); Document2D->ksTextLine(textItemParam); } //  Document2D->ksEndObj(); //  textItemFont.Unbind(); textItemParam.Unbind(); paragraphParam.Unbind(); dynamicArray->ksDeleteArray(); dynamicArray.Unbind(); 


在此示例中,首先将输出行写入DynamicArray ,然后才将其输出到段落。 这使您可以将信息与其表示分开。 如果在我们的示例中未使用NEW_LINE标志,则只需调用ksTextLine方法就可以解决。

该程序的结果类似于上一个示例的结果。

结论

在本课程中,我们研究了如何构建段落以及如何使用它显示多行文本。 我们还学会了将信息与演示分开。 不幸的是,多行文本的正确输出需要手动遍历字符串数组。 这不是很方便。 在下一课中,我将展示如何解决此问题。

要继续,请关注博客新闻。

Sergey Norseev博士,《在Delphi中进行COMPAS的应用程序开发》一书的作者。

Source: https://habr.com/ru/post/zh-CN434336/


All Articles