// EXTERNAL INCLUDES
#include <cmath>
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/font-client.h>
+
namespace Dali
{
namespace TextAbstraction
{
-void TransformToArcClockwise( const CircularTextParameters& parameters, double& x, double& y )
+void TransformToArc( const CircularTextParameters& parameters, double& x, double& y )
{
- double radius = parameters.radius;
- double angle = parameters.beginAngle;
+ double yP = y;
- angle -= parameters.invRadius * x;
+ // Does the italic synthesization for circular layout.
+ if( parameters.synthesizeItalic )
+ {
+ const double xP = -yP * sin( TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE );
+ yP *= cos( TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE );
- radius -= y;
- x = radius * cos( angle );
- y = -radius * sin( angle );
-
- x += parameters.centerX;
- y += parameters.centerY;
-}
+ x += xP;
+ }
-void TransformToArcAntiClockwise( const CircularTextParameters& parameters, double& x, double& y )
-{
+ double angle = 0.0;
double radius = parameters.radius;
- double angle = parameters.beginAngle;
- angle += parameters.invRadius * x;
+ // Transform to a circular layout.
+ if( parameters.isClockwise )
+ {
+ angle = parameters.beginAngle - parameters.invRadius * x;
+ radius -= yP;
+
+ x = radius * cos( angle );
+ y = -radius * sin( angle );
+ }
+ else
+ {
+ angle = parameters.beginAngle + parameters.invRadius * x;
+ radius += yP;
- radius += y;
- x = radius * cos( angle );
- y = radius * sin( -angle );
+ x = radius * cos( angle );
+ y = radius * sin( -angle );
+ }
+ // Transforms to the text area coordinate system.
x += parameters.centerX;
y += parameters.centerY;
}
radius{ 0.0 },
invRadius{ 0.0 },
beginAngle{ 0.0 },
- isClockwise{ true }
+ isClockwise{ true },
+ synthesizeItalic{ false }
{}
- double centerX; ///< The 'x' center of the circular path.
- double centerY; ///< The 'y' center of the circular path.
- double radius; ///< The radius in pixels.
- double invRadius; ///< 1.0 / radius.
- double beginAngle; ///< The angle in radians where the circular text begins.
- bool isClockwise:1; ///< Whether the circular text layout is clockwise.
+ double centerX; ///< The 'x' center of the circular path.
+ double centerY; ///< The 'y' center of the circular path.
+ double radius; ///< The radius in pixels.
+ double invRadius; ///< 1.0 / radius.
+ double beginAngle; ///< The angle in radians where the circular text begins.
+ bool isClockwise:1; ///< Whether the circular text layout is clockwise.
+ bool synthesizeItalic:1; ///< Whether to synthesize italic.
};
/**
- * @brief Transforms a vertex to wrap a clockwise circular path.
+ * @brief Transforms a vertex to wrap a circular path.
*
* @param[in] parameters The parameters of the circular path.
* @param[in,out] x The 'x' coordinate of the vertex.
* @param[in,out] y The 'y' coordinate of the vertex.
*/
-DALI_ADAPTOR_API void TransformToArcClockwise( const CircularTextParameters& parameters, double& x, double& y );
-
-/**
- * @brief Transforms a vertex to wrap an anti clockwise circular path.
- *
- * @param[in] parameters The parameters of the circular path.
- * @param[in,out] x The 'x' coordinate of the vertex.
- * @param[in,out] y The 'y' coordinate of the vertex.
- */
-DALI_ADAPTOR_API void TransformToArcAntiClockwise( const CircularTextParameters& parameters, double& x, double& y );
+DALI_ADAPTOR_API void TransformToArc( const CircularTextParameters& parameters, double& x, double& y );
} // namespace TextAbstraction
// Copy the path to get a cairo_path_t pointer used to iterate through all its items.
std::unique_ptr<cairo_path_t, void(*)(cairo_path_t*)> path( cairo_copy_path( circularCr ), cairo_path_destroy );
- void ( *transformToArc )( const Dali::TextAbstraction::CircularTextParameters&, double&, double& );
- transformToArc = parameters.isClockwise ? &Dali::TextAbstraction::TransformToArcClockwise : &Dali::TextAbstraction::TransformToArcAntiClockwise;
-
// Iterates through all the path items and transform each vertex to follow the circle.
// Transformed vertices are added to a new path in the 'cr' context (the one used to render the circular text)
for( int i = 0; i < path->num_data; i += path->data[i].header.length )
first = false;
double x = data[1].point.x;
double y = data[1].point.y;
- transformToArc( parameters, x, y );
+ Dali::TextAbstraction::TransformToArc( parameters, x, y );
cairo_move_to( cr, x, y );
break;
}
{
double x = data[1].point.x;
double y = data[1].point.y;
- transformToArc( parameters, x, y );
+ Dali::TextAbstraction::TransformToArc( parameters, x, y );
cairo_line_to( cr, x, y );
break;
}
double y2 = data[2].point.y;
double x3 = data[3].point.x;
double y3 = data[3].point.y;
- transformToArc( parameters, x1, y1 );
- transformToArc( parameters, x2, y2 );
- transformToArc( parameters, x3, y3 );
+ Dali::TextAbstraction::TransformToArc( parameters, x1, y1 );
+ Dali::TextAbstraction::TransformToArc( parameters, x2, y2 );
+ Dali::TextAbstraction::TransformToArc( parameters, x3, y3 );
cairo_curve_to( cr, x1, y1, x2, y2, x3, y3 );
break;
}
radians = fmod( radians, TWO_PI );
radians += ( radians < 0.f ) ? TWO_PI : 0.f;
- void ( *transformToArc )( const CircularTextParameters&, double&, double& );
- transformToArc = circularTextParameters.isClockwise ? &TransformToArcClockwise : &TransformToArcAntiClockwise;
-
- transformToArc( circularTextParameters, centerX, centerY );
+ TransformToArc( circularTextParameters, centerX, centerY );
uint8_t* pixelsOut = nullptr;
unsigned int widthOut = data.width;
static_cast<double>( color.a ) );
// Create the Cairo's font from the FreeType font.
- std::unique_ptr<cairo_font_face_t, void(*)(cairo_font_face_t*)> fontFacePtr( cairo_ft_font_face_create_for_ft_face( run.fontFace, 0 ), cairo_font_face_destroy );
+ int options = 0;
+ options = CAIRO_HINT_STYLE_SLIGHT;
+ std::unique_ptr<cairo_font_face_t, void(*)(cairo_font_face_t*)> fontFacePtr( cairo_ft_font_face_create_for_ft_face( run.fontFace, options ), cairo_font_face_destroy );
cairo_font_face_t* fontFace = fontFacePtr.get();
static const cairo_user_data_key_t key = { 0 };
// Render the glyphs.
if( isCircularText )
{
- // Create a new path where the text is laid out on a horizontal straight line.
- cairo_new_path( circularCr );
- cairo_move_to( circularCr, 0.0, 0.0 );
+ circularTextParameters.synthesizeItalic = synthesizeItalic;
+
+ const unsigned int glyphJump = circularTextParameters.synthesizeItalic ? 1u : run.numberOfGlyphs;
+
+ for( unsigned int index = 0u; index < run.numberOfGlyphs; index += glyphJump )
+ {
+ // Clears the current path where the text is laid out on a horizontal straight line.
+ cairo_new_path( circularCr );
+ cairo_move_to( circularCr, 0.0, 0.0 );
+
+ cairo_glyph_path( circularCr, ( cairoGlyphsBuffer + run.glyphIndex + index ), glyphJump );
- cairo_glyph_path( circularCr, ( cairoGlyphsBuffer + run.glyphIndex ), run.numberOfGlyphs );
- WrapToCircularPath( cr, circularCr, circularTextParameters );
+ WrapToCircularPath( cr, circularCr, circularTextParameters );
+ cairo_fill( cr );
+ }
}
else
{
cairo_matrix_init_identity( &matrix );
cairo_set_matrix( cr, &matrix );
}
+
+ cairo_fill( cr );
}
- cairo_fill( cr );
}
}