Usando objetos Glifo | Solución API para C++

Trabajar con glifos es crucial al codificar fuentes, ya que es su unidad. Cuando la información básica sobre los glifos se explica en el artículo del Qué es el párrafo de fuente, aquí le enseñaremos la funcionalidad de Aspose.Font para trabajar con glifos y los objetos Glifo en particular.

Objeto glifo

Los glifos de cualquier fuente se representan mediante el tipo Glyph en la biblioteca Aspose.Font.

Por lo tanto, el tipo Glifo es un objeto universal para los glifos de fuentes, independientemente del formato de fuente (TrueType, formato de fuente compacto, etc.).

La funcionalidad proporcionada por el objeto Glyph.

¿Qué funcionalidad nos proporciona este objeto?

Esta pregunta se responde por las propiedades que tiene.

Tengamos un ejemplo con el siguiente fragmento de código que muestra cómo calcular el ancho del texto “Hola mundo” en píxeles cuando el tamaño de fuente es 10.

Agregue los siguientes espacios de nombres al principio del archivo:

1using namespace Aspose::Font::Glyphs;
2System::SharedPtr<Aspose::Font::Font> font;

Entonces debes seguir los siguientes pasos:

 1    //Declare text and other constants
 2    const System::String text = u"Hello world";
 3    const int32_t fontSize = 10;
 4    
 5    //Declare variable for string width
 6    double width = 0;
 7    
 8    //Get glyph for each letter in text and calculate width for whole text.
 9    //The same result can be achieved using method font->get_Metrics()->MeasureString(text, fontSize).
10    for (char16_t symbol : text)
11    {
12        System::SharedPtr<GlyphId> gid = this->_font->get_Encoding()->DecodeToGid(symbol);
13        System::SharedPtr<Glyph> glyph = this->_font->GetGlyphById(gid);
14        width += (glyph->get_WidthVectorX() / this->_font->get_Metrics()->get_UnitsPerEM()) * fontSize;
15    }

Para obtener el cuadro delimitador del glifo, utilice la propiedad GlyphBBox del objeto Glyph.

Para obtener una representación visual de los glifos, necesita conocer las coordenadas de todos los puntos de los glifos.

¿Cómo obtener coordenadas para todos los puntos de glifo del objeto Glifo?

Las siguientes propiedades, IsEmpty y Path fueron diseñadas para este caso.

La propiedad IsEmpty es auxiliar. Nos dice si el camino del glifo está vacío o, en otras palabras, el glifo no tiene ninguna instrucción de dibujo. Si tiene el valor falso, es hora de construir la figura completa del glifo usando la muy útil propiedad Path.

En el concepto de la biblioteca Aspose.Font, la representación de cualquier glifo se divide en las primitivas gráficas más simples, llamadas segmentos, y representadas por la interfaz IPathSegment. La interfaz IPathSegment es una primitiva gráfica abstracta básica.

Las primitivas gráficas concretas están representadas por tipos como MoveTo, LineTo, CurveTo y ClosePath.

El tipo ClosePath se utiliza para indicar el final del contorno gráfico actual.

Los tipos MoveTo, LineTo y CurveTo por su definición corresponden con los operadores postscript idénticos.

Además, los tipos MoveTo y LineTo por su definición corresponden a las funciones MoveToEx() y LineTo() de la biblioteca GDI de Windows, el tipo CurveTo se usa para describir curvas Bézier.

La propiedad Glyph Path nos proporciona una colección de todas las primitivas gráficas para ese glifo. La propiedad Path tiene el tipo SegmentPath y cada objeto de este tipo tiene la propiedad Segments de tipo PathSegmentCollection. Esta propiedad Segmentos devuelve todas las primitivas gráficas que incluye el objeto SegmentPath. En otras palabras, podemos obtener todas las primitivas gráficas del glifo usando la entrada glifo.Path.Segments.

El siguiente ejemplo calcula todos los puntos que tiene el glifo y los almacena en puntos variables, que representan una matriz de objetos con tipo Punto.

La lógica utilizada por este ejemplo es simple y no extrae contornos de glifos. Para obtener estos contornos, se debe agregar el tipo ClosePath al procesamiento de segmentos.

Agregue los siguientes espacios de nombres al principio del archivo:

1using System::Collections::Generic;
2using System::Drawing;
3using Aspose::Font::Glyphs;
4using Aspose::Font::RenderingPath;

Entonces debes seguir los siguientes pasos:

 1    System::SharedPtr<Glyph> glyph;
 2
 3    //Declare resultant list with pints
 4    System::SharedPtr<System::Collections::Generic::List<System::Drawing::Point>> points = System::MakeObject<System::Collections::Generic::List<System::Drawing::Point>>();
 5    
 6    //Init service reference on IPathSegment
 7    System::SharedPtr<IPathSegment> prevSegment;
 8    
 9    //Iterate all glyph path segments and collect points
10    for (auto&& segment : glyph->get_Path()->get_Segments())
11    {
12        if ((System::ObjectExt::Is<LineTo>(segment)) || (System::ObjectExt::Is<CurveTo>(segment)))
13        {
14            if (System::ObjectExt::Is<MoveTo>(prevSegment))
15            {
16                System::SharedPtr<MoveTo> moveTo = System::DynamicCast_noexcept<Aspose::Font::RenderingPath::MoveTo>(prevSegment);
17                AddPoint((int32_t)moveTo->get_X(), (int32_t)moveTo->get_Y(), points);
18            }
19            if (System::ObjectExt::Is<LineTo>(segment))
20            {
21                System::SharedPtr<LineTo> line = System::DynamicCast_noexcept<Aspose::Font::RenderingPath::LineTo>(segment);
22                AddPoint((int32_t)line->get_X(), (int32_t)line->get_Y(), points);
23            }
24            else if (System::ObjectExt::Is<CurveTo>(segment))
25            {
26                System::SharedPtr<CurveTo> curve = System::DynamicCast_noexcept<Aspose::Font::RenderingPath::CurveTo>(segment);
27                AddPoint((int32_t)curve->get_X1(), (int32_t)curve->get_Y1(), points);
28                AddPoint((int32_t)curve->get_X2(), (int32_t)curve->get_Y2(), points);
29                AddPoint((int32_t)curve->get_X3(), (int32_t)curve->get_Y3(), points);
30            }
31        }
32        prevSegment = segment;
33    }	
34
35void GlyphMetrics::AddPoint(int32_t x, int32_t y, System::SharedPtr<System::Collections::Generic::List<System::Drawing::Point>> points)
36{
37    System::Drawing::Point p;
38    p.set_X(x);
39    p.set_Y(y);
40    points->Add(p);
41}

Todos los ejemplos de uso de Aspose.Font se almacenan en la solución Aspose.Font.Examples.CPP.sln, en los cpp-examples de la Documentación de Aspose.Font

Si tiene algún problema, puede publicarlo en la sección Aspose.Font.Product Family del Foro de soporte gratuito y dentro de unas horas nuestro equipo de soporte aclarará todo. para ti.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.