Trabajar con la API KOMPAS-3D → Lección 13 → Párrafos

Antes de pasar a formas documentadas de crear cadenas compuestas, necesitamos familiarizarnos con un objeto como un párrafo. Es un bloque de texto formateado automáticamente que consta de varias líneas. En esta lección, veremos cómo construir párrafos simples.



El contenido de la serie de lecciones "Trabajando con la API KOMPAS-3D"


  1. Los fundamentos
  2. Diseño de dibujo
  3. Conexión correcta a KOMPAS
  4. Inscripción principal
  5. Primitivas gráficas
  6. Guardar un documento en varios formatos
  7. Conociendo la configuración
  8. Métodos de escritura más sofisticados en el bloque de título
  9. Lectura de celdas de subtítulos
  10. Caracteres especiales que incluyen una cadena
  11. Etiquetas de texto simple
  12. Cuerdas compuestas
  13. Los párrafos
  14. Texto multilínea

Parámetros de párrafo ( ksParagraphParam )


La interfaz ksParagraphParam describe un párrafo. Para obtenerlo, debe usar el método GetParamStruct de la interfaz KompasObject , para esto debe pasarle la constante ko_ParagraphParam ( 0x0000001B ). Considere las propiedades de la interfaz ksParagraphParam .

ang - el ángulo del texto en grados. Se retrasa desde la línea horizontal en sentido antihorario. Similar al parámetro ang del método ksText .

altura : la altura del párrafo en milímetros.

hFormat : formatear el texto horizontalmente. Esta propiedad se usa cuando el texto no se ajusta al ancho del párrafo. Los valores válidos se enumeran en la tabla a continuación.



estilo : estilo del texto (descrito en la lección 11 ).

vFormat : formatear el texto verticalmente. Esta propiedad se usa cuando el texto no cabe en el párrafo en altura. Los valores válidos se enumeran en la tabla a continuación.



Hay dos cosas a tener en cuenta al trabajar con la propiedad vFormat :

  1. Según la documentación de KOMPAS, los valores válidos de la propiedad vFormat son 0 y -1 , pero esto no es así. Los valores válidos son 0 y 1 .
  2. COMPASS no cambia la altura de los caracteres. Solo cambia la distancia entre las líneas. Si la altura de las líneas es menor que la altura del párrafo, entonces pueden superponerse. Un ejemplo de dicha superposición se encuentra en la figura a continuación.



ancho : el ancho del párrafo en milímetros.
Las propiedades height , hFormat , vFormat y width nos permiten resolver el problema de colocar texto en un rectángulo dado. Este método es mucho más confiable y eficiente que el método ksGetTextLength discutido en la Lección 11 .

x e y son las coordenadas del punto de anclaje. La posición del párrafo con respecto al punto de anclaje a lo largo del eje horizontal se ajusta mediante el método ksSetTextAlign de la interfaz ksDocument2D (aunque esta posibilidad no está documentada). El punto de anclaje vertical siempre coincide con la parte inferior de la primera línea del párrafo. Este comportamiento no se puede cambiar.
La interfaz ksParagraphParam tiene un solo método: Init () . Inicializa los valores de propiedad de la interfaz. No tiene parámetros de entrada. Si tiene éxito, devuelve verdadero .

Párrafo de construcción


La creación de un párrafo consta de tres pasos secuenciales.

  1. Declaración de inicio de párrafo. Para hacer esto, se llama al método ksParagraph de la interfaz ksDocument2D . Como único parámetro, este método acepta la interfaz ksParagraphParam , que establece los parámetros del párrafo. Si tiene éxito, el método ksParagraph devuelve uno y, en caso de error, devuelve cero .
  2. Llenar el párrafo Para cada línea que se muestra en un párrafo, se llama al método ksTextLine de la interfaz ksDocument2D . Como único parámetro, acepta la interfaz ksTextItemParam o ksTextLineParam (discutida en lecciones anteriores en el bucle) que describe la cadena. Tenga en cuenta que las líneas de salida no deben contener los caracteres @ , $ , & , ~ , ^ y # , ya que son caracteres de control. Trabajar con ellos se considerará en las próximas lecciones del ciclo.
  3. Fin del parrafo. Para hacer esto, se llama al método ksEndObj () de la interfaz ksDocument2D . No tiene parámetros de entrada y, si tiene éxito, devuelve un puntero entero al objeto creado (párrafo). En caso de error, devuelve cero .

Un ejemplo El párrafo más simple


A continuación se muestra el código fuente del programa, que demuestra la construcción de un párrafo simple.
//  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(); 


Como siempre, aquí, por simplicidad, se omite el código responsable de la creación y ejecución del documento (este tema se discutió en lecciones anteriores).

En este ejemplo, KOMPAS determina el tamaño del párrafo en función de su contenido. La siguiente figura muestra el párrafo generado.



Nota: el texto se muestra como una sola línea. No especificamos el ancho del párrafo, por lo que KOMPAS lo aumenta automáticamente según sea necesario. Si se estableciera el ancho, el comportamiento de COMPASS estaría determinado por el valor de la propiedad hFormat de la interfaz ksParagraphParam .

Para formar un texto compuesto y de varias líneas, debe usar las características de dibujo que se discutieron parcialmente en la lección anterior.

Un ejemplo Texto multilínea


Para ajustar explícitamente a una nueva línea, use el indicador NEW_LINE ( 0x1000 ).

El siguiente es un programa de ejemplo que demuestra cómo construir un párrafo de varias líneas usando esta bandera.
 //  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(); 


En este ejemplo, se crea un párrafo de tres líneas. La primera línea se muestra como de costumbre. Para el segundo, se establece el indicador NEW_LINE . Él habla sobre el comienzo de una nueva línea. El tercero se muestra como de costumbre, pero el indicador NEW_LINE todavía está activo, ya que estamos trabajando con la misma instancia de la interfaz ksTextItemParam . La siguiente figura muestra el párrafo generado por este programa.


Ahora las líneas se muestran correctamente.

Desafíos para trabajar con párrafos


Alineación de texto


La alineación del texto se establece mediante el método ksSetTextLineAlign de la interfaz ksDocument2D . Solo tiene un parámetro entero: establecer la alineación. Sus valores válidos se enumeran en la tabla a continuación.



Si tiene éxito, el método ksSetTextLineAlign devuelve el indicador de alineación anterior y, en caso de error, devuelve -1 .

Tenga en cuenta que el método ksSetTextLineAlign solo se puede usar dentro del bloque (en nuestro caso, se usa dentro del párrafo). Esto significa que no se puede usar para establecer la alineación para la salida de texto mediante el método ksText . Esta limitación se debe al hecho de que, en este caso, KOMPAS no sabe con respecto a qué bordes es necesario alinear el texto.
Otro punto importante está relacionado con el alcance del método ksSetTextLineAlign , que afecta a las líneas de salida. Considere un ejemplo (aquí se usa una sintaxis muy simplificada en comparación con sus originales):

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

¿Cómo se alinearán las líneas? Contrariamente a nuestras expectativas, ambas líneas estarán alineadas a la derecha. Por qué El hecho es que el método ksSetTextLineAlign cambia en primer lugar la alineación de la última línea de salida. Esto es lo que sucede en nuestro ejemplo: la primera línea establece la alineación central. Como no hay una línea de salida anterior, esta llamada cambia la alineación predeterminada (izquierda).

Luego imprimimos la línea "Centro". Inicialmente, utiliza la alineación central establecida anteriormente.

En la tercera línea, nuevamente cambiamos la alineación. En primer lugar, el método cambia la alineación de la línea anterior ("Centro"). Por lo tanto, está alineado a la derecha y no al centro, como lo planeamos. La misma alineación se alinea por defecto.
Mostramos la línea "Derecha". Dado que el método ksSetTextLineAlign ya no se llama, utiliza la alineación establecida anteriormente (a la derecha).
Por lo tanto, ambas líneas están alineadas a la derecha. Ahora cambiemos un poco el ejemplo:

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

Todo lo que cambiamos fue agregar la salida de una cadena vacía sin cambiar la alineación. Ahora las líneas se muestran correctamente. Esto sucede porque la salida de una cadena vacía "absorbe" la alineación correcta establecida. La segunda llamada al método ksSetTextLineAlign afecta a una línea vacía y no afecta a la línea central de ninguna manera.
El siguiente ejemplo muestra la alineación correcta sin mostrar una cadena vacía.

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

Las llamadas ksTextLine y ksSetTextLineAlign se intercambian. Dado que el método ksSetTextLineAlign afecta principalmente a la última línea mostrada, las alineaciones se configuran correctamente y las líneas se muestran como queríamos.

Ejemplo


El siguiente es el código fuente de un programa que demuestra la alineación del texto en un párrafo.
 //  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(); 


En este ejemplo, además de la alineación del texto, también se demuestra el uso de las propiedades de ancho y hFormat de la interfaz ksParagraphParam . Se usan para limitar su ancho. Si no los cambiamos, KOMPAS aumentaría el ancho del párrafo, y no veríamos la alineación a la izquierda y al ancho.

Se muestran líneas en blanco para mejorar la legibilidad del párrafo. No afectan la alineación correcta.

La siguiente figura muestra el párrafo generado por este programa.



Activa o desactiva el estilo


En la undécima lección del ciclo, examinamos las banderas que controlan el estilo ( ITALIC_ON , ITALIC_OFF , BOLD_ON , UNDERLINE_ON y UNDERLINE_OFF ). Luego los examinamos en relación con el método ksText . Una diferencia importante entre su uso en un párrafo es que la acción no se limita a llamar al método ksTextLine , sino que se extiende a todo el párrafo. Veamos algunos ejemplos.

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

La primera línea se mostrará en negrita. No hay preguntas con esto. Pero, ¿cómo se mostrará la segunda línea? La bandera BOLD_ON se ha restablecido para ella. Por lo tanto, podemos suponer que se mostrará en una fuente normal. Pero esto no es así. Después de cumplir con el indicador BOLD_ON , KOMPAS entiende el comando de la siguiente manera: todas las líneas posteriores de este párrafo se muestran en negrita. Por lo tanto, todas las líneas posteriores se muestran en negrita hasta que se completa el párrafo o KOMPAS encuentra el indicador BOLD_OFF emparejado con él . Considere un ejemplo:

 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 primera línea se muestra en negrita. Para la segunda línea, borramos la bandera BOLD_ON y activamos la bandera BOLD_OFF emparejada con ella , lo que cancela el estilo en negrita. Debido a esto, las líneas segunda y tercera se muestran sin negrita.

Este comportamiento se aplica a las banderas ITALIC_ON , ITALIC_OFF , UNDERLINE_ON y UNDERLINE_OFF , pero no se aplica a la bandera NEW_LINE , ya que no tiene un par de banderas anuladas.

Ejemplo


El siguiente es el código fuente del programa, que muestra la salida de texto con diferentes estilos usando párrafos.
 //  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 parte más importante de este programa es la configuración adecuada de banderas para las líneas de salida. Analicemos con más detalle (las líneas correspondientes del programa están marcadas con un par de caracteres " // ").

La primera línea se muestra sin ningún cambio. Por lo tanto, no hay banderas establecidas para ello.

La segunda línea debe mostrarse sin pendiente y con una nueva línea. Por lo tanto, los indicadores están configurados para ello: NEW_LINE (comenzar en una nueva línea) e ITALIC_OFF (desactivar cursiva ).

La tercera línea debe aparecer en cursiva y negrita. Para hacer esto, activamos las banderas: NEW_LINE , ITALIC_ON ( habilitar cursiva) y BOLD_ON ( habilitar caras en negrita). Todas las demás banderas se reinician.

La cuarta línea debe imprimirse en cursiva, subrayada y no en negrita. Para hacer esto, activamos las banderas: NEW_LINE , BOLD_OFF (deshabilitar negrita, izquierda de la línea anterior) y UNDERLINE_ON (habilitar subrayado).

Si hubiera más líneas en el párrafo, se mostrarían en letra cursiva subrayada. Para deshabilitar el estilo subrayado, debe borrar el indicador UNDERLINE_ON y activar el indicador UNDERLINE_OFF .

La siguiente figura muestra el resultado de este programa.



Separar información de la presentación


Si sigue la estructura de sus programas, probablemente haya notado un serio inconveniente del ejemplo anterior: el código responsable de generar la salida se mezcla con el código responsable de implementar su salida. Con un buen estilo de programación, se acostumbra separar la información de su presentación.

Si la información de salida consta de varias líneas de ksTextItemParam , entonces se pueden combinar en una interfaz ksTextLineParam . El método ksTextLine puede manejar ambas interfaces. Pero este enfoque tiene una limitación desagradable: si el método ksTextLine acepta la interfaz ksTextLineParam , los indicadores NEW_LINE (y SPECIAL_SYMBOL_END ) se ignoran. Es decir, toda la información se mostrará en una línea, incluso si el indicador NEW_LINE está configurado para algunas instancias de ksTextItemParam . Para evitar esta limitación, debe llamar manualmente a ksTextLine para cada línea.

El siguiente es el código fuente de un ejemplo que demuestra esta técnica.
 //    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(); 


En este ejemplo, las líneas de salida se escriben primero en DynamicArray y solo luego se envían al párrafo. Esto le permite separar la información de su presentación. Si el indicador NEW_LINE no se usó en nuestro ejemplo, entonces podríamos pasar con una llamada al método ksTextLine .

El resultado de este programa es similar al resultado del ejemplo anterior.

Conclusión

En esta lección, vimos cómo construir un párrafo y cómo usarlo para mostrar texto de varias líneas. También aprendimos a separar la información de su presentación. Desafortunadamente, la salida correcta del texto de varias líneas requiere un recorrido manual de una serie de cadenas. Esto no es muy conveniente. En la próxima lección mostraré cómo resolver este problema.

Para continuar, sigue las noticias del blog.

Sergey Norseev, Ph.D., autor del libro "Desarrollo de aplicaciones para COMPAS en Delphi".

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


All Articles