Travailler avec l'API KOMPAS-3D → Leçon 13 → Paragraphes

Avant de passer à des méthodes documentées pour créer des chaînes composées, nous devons nous familiariser avec un objet tel qu'un paragraphe. Il s'agit d'un bloc de texte formaté automatiquement composé de plusieurs lignes. Dans cette leçon, nous verrons comment créer des paragraphes simples.



Le contenu de la série de leçons «Travailler avec l'API COMPASS-3D


  1. Les bases
  2. Conception de dessin
  3. Connexion correcte à KOMPAS
  4. Inscription principale
  5. Primitives graphiques
  6. Enregistrement d'un document dans différents formats
  7. Connaître les paramètres
  8. Méthodes d'écriture plus sophistiquées dans le cartouche
  9. Lecture des cellules de légende
  10. Caractères spéciaux dont une chaîne
  11. Étiquettes de texte simples
  12. Chaînes composées
  13. Paragraphes
  14. Texte multiligne

Paramètres de paragraphe ( ksParagraphParam )


Un paragraphe est décrit par l'interface ksParagraphParam . Pour l'obtenir, vous devez utiliser la méthode GetParamStruct de l'interface KompasObject , pour cela, vous devez lui passer la constante ko_ParagraphParam ( 0x0000001B ). Considérez les propriétés de l'interface ksParagraphParam .

ang - l'angle du texte en degrés. Il est retardé de la ligne horizontale dans le sens antihoraire. Similaire au paramètre ang de la méthode ksText .

hauteur - la hauteur du paragraphe en millimètres.

hFormat - formatage horizontal du texte. Cette propriété est utilisée lorsque le texte ne tient pas dans le paragraphe en largeur. Les valeurs valides sont répertoriées dans le tableau ci-dessous.



style - style du texte (décrit dans la leçon 11 ).

vFormat - formatage vertical du texte. Cette propriété est utilisée lorsque le texte ne tient pas dans le paragraphe en hauteur. Les valeurs valides sont répertoriées dans le tableau ci-dessous.



Il y a deux choses à garder à l'esprit lorsque vous travaillez avec la propriété vFormat :

  1. Selon la documentation de KOMPAS, les valeurs valides de la propriété vFormat sont 0 et -1 , mais ce n'est pas le cas. Les valeurs valides sont 0 et 1 .
  2. COMPASS ne modifie pas la hauteur des caractères. Cela ne fait que modifier la distance entre les lignes. Si la hauteur des lignes est inférieure à la hauteur du paragraphe, elles peuvent se chevaucher. Un exemple d'une telle superposition est illustré dans la figure ci-dessous.



largeur - la largeur du paragraphe en millimètres.
Les propriétés height , hFormat , vFormat et width nous permettent de résoudre le problème de placement de texte dans un rectangle donné. Cette méthode est beaucoup plus fiable et efficace que la méthode ksGetTextLength discutée dans la leçon 11 .

x et y sont les coordonnées du point d'ancrage. La position du paragraphe par rapport au point d'ancrage le long de l'axe horizontal est ajustée par la méthode ksSetTextAlign de l'interface ksDocument2D (bien que cette possibilité ne soit pas documentée). Le point d'ancrage vertical correspond toujours au bas de la première ligne du paragraphe. Ce comportement ne peut pas être modifié.
L'interface ksParagraphParam n'a qu'une seule méthode: Init () . Il initialise les valeurs de propriété de l'interface. Il n'a pas de paramètres d'entrée. En cas de succès, renvoie true .

Construction de paragraphe


La création d'un paragraphe se compose de trois étapes séquentielles.

  1. Déclaration du début du paragraphe. Pour ce faire, la méthode ksParagraph de l'interface ksDocument2D est appelée . Comme seul paramètre, cette méthode accepte l'interface ksParagraphParam , qui définit les paramètres du paragraphe. En cas de succès, la méthode ksParagraph renvoie un, et en cas d'erreur, renvoie zéro .
  2. Remplir le paragraphe. Pour chaque ligne affichée dans un paragraphe, la méthode ksTextLine de l'interface ksDocument2D est appelée . En tant que seul paramètre, il accepte l' interface ksTextItemParam ou ksTextLineParam (décrite dans les leçons précédentes de la boucle) qui décrivent la chaîne. Veuillez noter que les lignes de sortie ne doivent pas contenir les caractères @ , $ , & , ~ , ^ et # , car ce sont des caractères de contrôle. Le travail avec eux sera envisagé dans les prochaines leçons du cycle.
  3. Fin du paragraphe. Pour ce faire, la méthode ksEndObj () de l'interface ksDocument2D est appelée . Il n'a aucun paramètre d'entrée et, en cas de succès, renvoie un pointeur entier vers l'objet créé (paragraphe). En cas d'erreur, il renvoie zéro .

Un exemple. Le paragraphe le plus simple


Ci-dessous se trouve le code source du programme, démontrant la construction d'un simple paragraphe.
//  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(); 


Comme toujours, ici, par souci de simplicité, le code responsable de la création et de l'exécution du document est omis (ce sujet a été discuté dans les leçons précédentes).

Dans cet exemple, KOMPAS détermine lui-même la taille du paragraphe en fonction de son contenu. La figure ci-dessous montre le paragraphe généré.



Attention: le texte est affiché sur une seule ligne. Nous n'avons pas spécifié la largeur du paragraphe, donc KOMPAS l'augmente automatiquement si nécessaire. Si la largeur était définie, le comportement COMPASS serait déterminé par la valeur de la propriété hFormat de l'interface ksParagraphParam .

Pour former un texte composé de plusieurs lignes et composé, vous devez utiliser les fonctions de dessin partiellement décrites dans la leçon précédente.

Un exemple. Texte multiligne


Pour encapsuler explicitement sur une nouvelle ligne, utilisez l'indicateur NEW_LINE ( 0x1000 ).

Voici un exemple de programme qui illustre la création d'un paragraphe multiligne à l'aide de cet indicateur.
 //  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(); 


Dans cet exemple, un paragraphe de trois lignes est créé. La première ligne s'affiche comme d'habitude. Pour le second, le drapeau NEW_LINE est défini . Il parle du début d'une nouvelle ligne. Le troisième est affiché comme d'habitude, mais le drapeau NEW_LINE est toujours actif pour cela, car nous travaillons avec la même instance de l'interface ksTextItemParam . La figure ci-dessous montre le paragraphe généré par ce programme.


Maintenant, les lignes s'affichent correctement.

Défis pour travailler avec des paragraphes


Alignement du texte


L'alignement du texte est défini par la méthode ksSetTextLineAlign de l'interface ksDocument2D . Il n'a qu'un seul paramètre entier - aligner l'ensemble. Ses valeurs valides sont répertoriées dans le tableau ci-dessous.



En cas de succès, la méthode ksSetTextLineAlign renvoie le drapeau d'alignement précédent et, en cas d'erreur, renvoie -1 .

Notez que la méthode ksSetTextLineAlign ne peut être utilisée qu'à l'intérieur du bloc (dans notre cas, elle est utilisée à l'intérieur du paragraphe). Cela signifie qu'il ne peut pas être utilisé pour définir l'alignement pour la sortie de texte par la méthode ksText . Cette limitation est due au fait que dans ce cas, KOMPAS ne sait pas par rapport aux limites sur lesquelles le texte doit être aligné.
Un autre point important est lié à la portée de la méthode ksSetTextLineAlign - quelles lignes de sortie elle affecte. Prenons un exemple (une syntaxe très simplifiée est utilisée ici par rapport à leurs originaux):

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

Comment les lignes seront-elles alignées? Contrairement à nos attentes, les deux lignes seront alignées à droite. Pourquoi? Le fait est que la méthode ksSetTextLineAlign modifie tout d'abord l'alignement de la dernière ligne de sortie. Voici ce qui se passe dans notre exemple: la première ligne définit l'alignement central. Puisqu'il n'y a pas de ligne de sortie précédente, cet appel modifie l'alignement par défaut (gauche).

Ensuite, nous imprimons la ligne «Centre». Initialement, il utilise l'alignement central défini précédemment.

Dans la troisième ligne, nous modifions à nouveau l'alignement. Tout d'abord, la méthode modifie l'alignement de la ligne précédente ("Centre"). Par conséquent, il est aligné à droite et non au centre, comme nous l'avions prévu. Le même alignement devient aligné par défaut.
Nous affichons la ligne "Droite". Étant donné que la méthode ksSetTextLineAlign n'est plus appelée, elle utilise l'alignement précédemment défini (à droite).
Ainsi, les deux lignes sont alignées à droite. Maintenant, changeons un peu l'exemple:

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

Tout ce que nous avons changé était d'ajouter la sortie d'une chaîne vide sans changer l'alignement. Maintenant, les lignes s'affichent correctement. Cela se produit car la sortie d'une chaîne vide «absorbe» l'alignement défini à droite. Le deuxième appel à la méthode ksSetTextLineAlign affecte une ligne vide et n'affecte en aucune façon la ligne centrale.
L'exemple ci-dessous montre l'alignement correct sans afficher une chaîne vide.

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

Les appels ksTextLine et ksSetTextLineAlign sont échangés. Étant donné que la méthode ksSetTextLineAlign affecte principalement la dernière ligne affichée, les alignements sont définis correctement et les lignes s'affichent comme nous le souhaitions.

Exemple


Voici le code source d'un programme qui illustre l'alignement du texte dans un paragraphe.
 //  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(); 


Dans cet exemple, en plus de l'alignement du texte, l'utilisation des propriétés width et hFormat de l'interface ksParagraphParam est également illustrée. Ils sont utilisés pour limiter sa largeur. Si nous ne les modifions pas, KOMPAS augmenterait la largeur du paragraphe et nous ne verrions pas l'alignement à gauche et à la largeur.

Des lignes vides sont affichées pour améliorer la lisibilité du paragraphe. Ils n'affectent pas l'alignement correct.

La figure ci-dessous montre le paragraphe généré par ce programme.



Activer ou désactiver le style


Dans la 11ème leçon du cycle, nous avons examiné les drapeaux qui contrôlent le style ( ITALIC_ON , ITALIC_OFF , BOLD_ON , UNDERLINE_ON et UNDERLINE_OFF ). Nous les avons ensuite examinés en relation avec la méthode ksText . Une différence importante entre leur utilisation dans un paragraphe est que l'action ne se limite pas à appeler la méthode ksTextLine , mais s'étend à l'ensemble du paragraphe. Regardons quelques exemples.

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

La première ligne sera affichée en gras. Il n'y a aucune question à ce sujet. Mais comment la deuxième ligne sera-t-elle affichée? Le drapeau BOLD_ON a été réinitialisé pour elle. Par conséquent, nous pouvons supposer qu'il sera affiché en police régulière. Mais ce n'est pas le cas. Ayant rencontré le drapeau BOLD_ON , KOMPAS comprend la commande comme suit: toutes les lignes suivantes de ce paragraphe sont affichées en gras. Par conséquent, toutes les lignes suivantes sont affichées en gras jusqu'à ce que le paragraphe soit terminé ou que KOMPAS rencontre l'indicateur BOLD_OFF qui lui est associé . Prenons un exemple:

 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); 

La première ligne s'affiche en gras. Pour la deuxième ligne, nous effaçons le drapeau BOLD_ON et armons le drapeau BOLD_OFF qui lui est associé , ce qui annule le style gras. Pour cette raison, les deuxième et troisième lignes sont affichées sans gras.

Ce comportement s'applique aux indicateurs ITALIC_ON , ITALIC_OFF , UNDERLINE_ON et UNDERLINE_OFF , mais ne s'applique pas à l'indicateur NEW_LINE , car il n'a pas une paire d'indicateurs de remplacement.

Exemple


Ce qui suit est le code source du programme, montrant la sortie de texte avec différents styles à l'aide de paragraphes.
 //  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(); 


La partie la plus importante de ce programme est le réglage correct des drapeaux pour les lignes de sortie. Analysons-le plus en détail (les lignes correspondantes du programme sont marquées par une paire de caractères « // »).

La première ligne s'affiche sans aucune modification. Par conséquent, aucun indicateur n'est défini pour cela.

La deuxième ligne doit être affichée sans pente et avec une nouvelle ligne. Par conséquent, les drapeaux sont définis pour cela: NEW_LINE (commencer sur une nouvelle ligne) et ITALIC_OFF (désactiver l' italique ).

La troisième ligne doit apparaître en italique et en gras. Pour ce faire, nous armons les drapeaux: NEW_LINE , ITALIC_ON ( activer les italiques) et BOLD_ON ( activer les visages en gras). Tous les autres drapeaux sont réinitialisés.

La quatrième ligne doit être imprimée en italique, soulignée et non en gras. Pour ce faire, nous armons les drapeaux: NEW_LINE , BOLD_OFF (désactivez bold, laissé sur la ligne précédente) et UNDERLINE_ON (activez souligné).

S'il y avait plus de lignes dans le paragraphe, elles seraient affichées en italique souligné. Pour désactiver le style souligné, vous devez désactiver le drapeau UNDERLINE_ON et armer le drapeau UNDERLINE_OFF .

La figure ci-dessous montre le résultat de ce programme.



Séparation des informations de la présentation


Si vous suivez la structure de vos programmes, vous avez probablement remarqué un sérieux inconvénient de l'exemple précédent: le code responsable de la génération de la sortie est mélangé avec le code responsable de l'implémentation de sa sortie. Avec un bon style de programmation, il est habituel de séparer les informations de leur présentation.

Si les informations de sortie se composent de plusieurs lignes de ksTextItemParam , elles peuvent être combinées en une seule interface ksTextLineParam . La méthode ksTextLine peut gérer ces deux interfaces. Mais cette approche a une limitation désagréable: si la méthode ksTextLine accepte l'interface ksTextLineParam , les indicateurs NEW_LINE (et SPECIAL_SYMBOL_END ) sont ignorés. Autrement dit, toutes les informations seront affichées sur une seule ligne, même si l'indicateur NEW_LINE est défini pour certaines instances de ksTextItemParam . Pour contourner cette limitation, vous devez appeler manuellement ksTextLine pour chaque ligne.

Voici le code source d'un exemple illustrant cette technique.
 //    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(); 


Dans cet exemple, les lignes de sortie sont d'abord écrites dans DynamicArray , puis seulement dans le paragraphe. Cela vous permet de séparer les informations de leur présentation. Si l'indicateur NEW_LINE n'était pas utilisé dans notre exemple, nous pourrions nous en tirer avec un seul appel à la méthode ksTextLine .

Le résultat de ce programme est similaire au résultat de l'exemple précédent.

Conclusion

Dans cette leçon, nous avons vu comment créer un paragraphe et comment l'utiliser pour afficher du texte sur plusieurs lignes. Nous avons également appris à séparer les informations de leur présentation. Malheureusement, la sortie correcte d'un texte sur plusieurs lignes nécessite une traversée manuelle d'un tableau de chaînes. Ce n'est pas très pratique. Dans la prochaine leçon, je montrerai comment résoudre ce problème.

Pour continuer, suivez l'actualité du blog.

Sergey Norseev, Ph.D., auteur du livre "Application Development for COMPAS in Delphi".

Source: https://habr.com/ru/post/fr434336/


All Articles