From 20a7c6fb7964e0f4a2695a37615cebcfd05c34ea Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Mon, 11 Mar 2019 11:12:42 +0000 Subject: [PATCH] Italic synthesize for circular layout. * Italic synthesization for circular layout was missing. * Hint flag added to the cairo renderer pipeline. Change-Id: Ic0bfe41b9419cca9483fd74a7e65f859cef08a69 Signed-off-by: Victor Cebollada --- .../text-renderer-layout-helper.cpp | 48 ++++++++++++++-------- .../text-abstraction/text-renderer-layout-helper.h | 29 +++++-------- .../text/text-abstraction/cairo-renderer.cpp | 44 +++++++++++--------- 3 files changed, 66 insertions(+), 55 deletions(-) diff --git a/dali/devel-api/text-abstraction/text-renderer-layout-helper.cpp b/dali/devel-api/text-abstraction/text-renderer-layout-helper.cpp index b5a3eb4..5e17f9f 100755 --- a/dali/devel-api/text-abstraction/text-renderer-layout-helper.cpp +++ b/dali/devel-api/text-abstraction/text-renderer-layout-helper.cpp @@ -21,38 +21,50 @@ // EXTERNAL INCLUDES #include +// INTERNAL INCLUDES +#include + 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; } diff --git a/dali/devel-api/text-abstraction/text-renderer-layout-helper.h b/dali/devel-api/text-abstraction/text-renderer-layout-helper.h index 95921a1..a502967 100755 --- a/dali/devel-api/text-abstraction/text-renderer-layout-helper.h +++ b/dali/devel-api/text-abstraction/text-renderer-layout-helper.h @@ -39,34 +39,27 @@ struct DALI_ADAPTOR_API CircularTextParameters 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 diff --git a/dali/internal/text/text-abstraction/cairo-renderer.cpp b/dali/internal/text/text-abstraction/cairo-renderer.cpp index d65e1dd..18e0fcc 100755 --- a/dali/internal/text/text-abstraction/cairo-renderer.cpp +++ b/dali/internal/text/text-abstraction/cairo-renderer.cpp @@ -154,9 +154,6 @@ void WrapToCircularPath( cairo_t* cr, cairo_t* circularCr, const Dali::TextAbstr // Copy the path to get a cairo_path_t pointer used to iterate through all its items. std::unique_ptr 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 ) @@ -175,7 +172,7 @@ void WrapToCircularPath( cairo_t* cr, cairo_t* circularCr, const Dali::TextAbstr 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; } @@ -183,7 +180,7 @@ void WrapToCircularPath( cairo_t* cr, cairo_t* circularCr, const Dali::TextAbstr { 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; } @@ -195,9 +192,9 @@ void WrapToCircularPath( cairo_t* cr, cairo_t* circularCr, const Dali::TextAbstr 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; } @@ -541,10 +538,7 @@ Devel::PixelBuffer RenderTextCairo( const TextAbstraction::TextRenderer::Paramet 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; @@ -788,7 +782,9 @@ Devel::PixelBuffer RenderTextCairo( const TextAbstraction::TextRenderer::Paramet static_cast( color.a ) ); // Create the Cairo's font from the FreeType font. - std::unique_ptr 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 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 }; @@ -824,12 +820,21 @@ Devel::PixelBuffer RenderTextCairo( const TextAbstraction::TextRenderer::Paramet // 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 { @@ -864,8 +869,9 @@ Devel::PixelBuffer RenderTextCairo( const TextAbstraction::TextRenderer::Paramet cairo_matrix_init_identity( &matrix ); cairo_set_matrix( cr, &matrix ); } + + cairo_fill( cr ); } - cairo_fill( cr ); } } -- 2.7.4