From 3e30971f9884dc48e80ef82de4ef85fc9dba1229 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Tue, 14 Jun 2016 17:00:25 +0100 Subject: [PATCH] Fix for multi-language support. * Characters common for all scripts (i.e. white spaces or zero width joiners) may be set a different font than the surrounding characters. In some languages it causes a group of characters to be shaped in different groups of glyphs. Change-Id: I0605572084252f9f3e8dab76a99d89c565924986 Signed-off-by: Victor Cebollada --- .../dali-toolkit-internal/utc-Dali-Text-Layout.cpp | 97 ++++----- .../utc-Dali-Text-MultiLanguage.cpp | 35 ++- dali-toolkit/internal/text/logical-model-impl.cpp | 3 +- .../text/multi-language-helper-functions.cpp | 6 +- .../text/multi-language-helper-functions.h | 2 + .../internal/text/multi-language-support-impl.cpp | 240 ++++++++++++--------- .../internal/text/multi-language-support-impl.h | 2 +- 7 files changed, 234 insertions(+), 151 deletions(-) diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp index 219fba1..7164972 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp @@ -1014,7 +1014,7 @@ int UtcDaliTextLayoutMultilineText02(void) 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -0.f, 44.f, -10.f, 55.f, -13.f, 62.f, -10.f, 67.f, -10.f, 75.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 32.f, -2.f, 35.f, -11.f, 1.f, -10.f, 12.f, -13.f, 19.f, -10.f, 24.f, -10.f, 32.f, -0.f, 37.f, -10.f, 45.f, -10.f, 50.f, -13.f, 58.f, -10.f, 66.f, -0.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -3.f, }; struct LineRun line0 = @@ -1069,10 +1069,10 @@ int UtcDaliTextLayoutMultilineText02(void) { { 38u, 12u }, { 38u, 12u }, - 79.f, + 80.f, 15.f, -5.f, - 3.f, + 4.f, 0.f, false, false @@ -1660,16 +1660,16 @@ int UtcDaliTextUpdateLayout01(void) 0.f, -9.f, 11.f, -9.f, 21.f, -9.f, 27.f, -13.f, 30.f, -13.f, 39.f, -0.f, 44.f, -10.f, 55.f, -13.f, 62.f, -10.f, 67.f, -10.f, 75.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 30.f, -0.f, 1.f, -10.f, 12.f, -13.f, 19.f, -10.f, 24.f, -10.f, 32.f, -0.f, 37.f, -10.f, 45.f, -10.f, 50.f, -13.f, 58.f, -10.f, 66.f, -0.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, - 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -3.f, 42.f, -12.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, + 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -3.f, 42.f, -11.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, 0.f, -8.f, 7.f, -6.f, 12.f, -7.f, 18.f, -7.f, 23.f, -11.f, 25.f, -0.f, 27.f, -7.f, 32.f, -11.f, 33.f, -11.f, 37.f, -8.f, 44.f, -11.f, 45.f, -11.f, 49.f, -8.f, 55.f, -0.f, 59.f, -10.f, 70.f, -13.f, 77.f, -10.f, 82.f, -10.f, 90.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 30.f, -0.f, - 1.f, -12.f, 12.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -9.f, 51.f, -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -0.f, - 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -0.f, 44.f, -10.f, 55.f, -13.f, 62.f, -10.f, 67.f, -10.f, 75.f, -0.f, + 1.f, -12.f, 12.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 41.f, -9.f, 52.f, -9.f, 62.f, -9.f, 68.f, -13.f, 71.f, -13.f, 80.f, -0.f, + 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -0.f, 45.f, -10.f, 56.f, -13.f, 63.f, -10.f, 68.f, -10.f, 76.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 32.f, -2.f, 35.f, -11.f, 1.f, -10.f, 12.f, -13.f, 19.f, -10.f, 24.f, -10.f, 32.f, -0.f, 37.f, -10.f, 45.f, -10.f, 50.f, -13.f, 58.f, -10.f, 66.f, -0.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, 0.f, -8.f, 7.f, -6.f, 12.f, -7.f, 18.f, -7.f, 23.f, -11.f, 25.f, -0.f, 27.f, -7.f, 32.f, -11.f, 33.f, -11.f, 37.f, -8.f, 44.f, -11.f, 45.f, -11.f, 49.f, -8.f, 55.f, -0.f, }; struct LineRun line01 = @@ -1715,7 +1715,7 @@ int UtcDaliTextUpdateLayout01(void) 92.f, 15.f, -5.f, - 4.f, + 5.f, 0.f, false, false @@ -1760,10 +1760,10 @@ int UtcDaliTextUpdateLayout01(void) { { 74u, 12u }, { 74u, 12u }, - 79.f, + 80.f, 15.f, -5.f, - 3.f, + 4.f, 0.f, false, false @@ -1784,10 +1784,10 @@ int UtcDaliTextUpdateLayout01(void) { { 92u, 12u }, { 92u, 12u }, - 78.f, + 79.f, 15.f, -5.f, - 4.f, + 5.f, 0.f, false, false @@ -1820,10 +1820,10 @@ int UtcDaliTextUpdateLayout01(void) { { 128u, 12u }, { 128u, 12u }, - 81.f, + 82.f, 15.f, -5.f, - 3.f, + 4.f, 0.f, false, false @@ -1832,7 +1832,7 @@ int UtcDaliTextUpdateLayout01(void) { { 140u, 10u }, { 140u, 10u }, - 76.f, + 77.f, 15.f, -5.f, 4.f, @@ -1868,7 +1868,7 @@ int UtcDaliTextUpdateLayout01(void) { { 166u, 12u }, { 166u, 12u }, - 79.f, + 80.f, 15.f, -5.f, 4.f, @@ -2187,16 +2187,16 @@ int UtcDaliTextUpdateLayout02(void) 0.f, -9.f, 11.f, -9.f, 21.f, -9.f, 27.f, -13.f, 30.f, -13.f, 39.f, -0.f, 44.f, -10.f, 55.f, -13.f, 62.f, -10.f, 67.f, -10.f, 75.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 30.f, -0.f, 1.f, -10.f, 12.f, -13.f, 19.f, -10.f, 24.f, -10.f, 32.f, -0.f, 37.f, -10.f, 45.f, -10.f, 50.f, -13.f, 58.f, -10.f, 66.f, -0.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, - 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -3.f, 42.f, -12.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, + 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -3.f, 42.f, -11.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, 0.f, -8.f, 7.f, -6.f, 12.f, -7.f, 18.f, -7.f, 23.f, -11.f, 25.f, -0.f, 27.f, -7.f, 32.f, -11.f, 33.f, -11.f, 37.f, -8.f, 44.f, -11.f, 45.f, -11.f, 49.f, -8.f, 55.f, -0.f, 59.f, -10.f, 70.f, -13.f, 77.f, -10.f, 82.f, -10.f, 90.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 30.f, -0.f, - 1.f, -12.f, 12.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -9.f, 51.f, -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -0.f, - 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -0.f, 44.f, -10.f, 55.f, -13.f, 62.f, -10.f, 67.f, -10.f, 75.f, -0.f, + 1.f, -12.f, 12.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 41.f, -9.f, 52.f, -9.f, 62.f, -9.f, 68.f, -13.f, 71.f, -13.f, 80.f, -0.f, + 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -0.f, 45.f, -10.f, 56.f, -13.f, 63.f, -10.f, 68.f, -10.f, 76.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 32.f, -2.f, 35.f, -11.f, 1.f, -10.f, 12.f, -13.f, 19.f, -10.f, 24.f, -10.f, 32.f, -0.f, 37.f, -10.f, 45.f, -10.f, 50.f, -13.f, 58.f, -10.f, 66.f, -0.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, 0.f, -8.f, 7.f, -6.f, 12.f, -7.f, 18.f, -7.f, 23.f, -11.f, 25.f, -0.f, 27.f, -7.f, 32.f, -11.f, 33.f, -11.f, 37.f, -8.f, 44.f, -11.f, 45.f, -11.f, 49.f, -8.f, 55.f, -0.f, }; struct LineRun line01 = @@ -2242,7 +2242,7 @@ int UtcDaliTextUpdateLayout02(void) 92.f, 15.f, -5.f, - 4.f, + 5.f, 0.f, false, false @@ -2287,10 +2287,10 @@ int UtcDaliTextUpdateLayout02(void) { { 74u, 12u }, { 74u, 12u }, - 79.f, + 80.f, 15.f, -5.f, - 3.f, + 4.f, 0.f, false, false @@ -2311,10 +2311,10 @@ int UtcDaliTextUpdateLayout02(void) { { 92u, 12u }, { 92u, 12u }, - 78.f, + 79.f, 15.f, -5.f, - 4.f, + 5.f, 0.f, false, false @@ -2347,10 +2347,10 @@ int UtcDaliTextUpdateLayout02(void) { { 128u, 12u }, { 128u, 12u }, - 81.f, + 82.f, 15.f, -5.f, - 3.f, + 4.f, 0.f, false, false @@ -2359,7 +2359,7 @@ int UtcDaliTextUpdateLayout02(void) { { 140u, 10u }, { 140u, 10u }, - 76.f, + 77.f, 15.f, -5.f, 4.f, @@ -2395,7 +2395,7 @@ int UtcDaliTextUpdateLayout02(void) { { 166u, 12u }, { 166u, 12u }, - 79.f, + 80.f, 15.f, -5.f, 4.f, @@ -2714,16 +2714,16 @@ int UtcDaliTextUpdateLayout03(void) 0.f, -9.f, 11.f, -9.f, 21.f, -9.f, 27.f, -13.f, 30.f, -13.f, 39.f, -0.f, 44.f, -10.f, 55.f, -13.f, 62.f, -10.f, 67.f, -10.f, 75.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 30.f, -0.f, 1.f, -10.f, 12.f, -13.f, 19.f, -10.f, 24.f, -10.f, 32.f, -0.f, 37.f, -10.f, 45.f, -10.f, 50.f, -13.f, 58.f, -10.f, 66.f, -0.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, - 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -3.f, 42.f, -12.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, + 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -3.f, 42.f, -11.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, 0.f, -8.f, 7.f, -6.f, 12.f, -7.f, 18.f, -7.f, 23.f, -11.f, 25.f, -0.f, 27.f, -7.f, 32.f, -11.f, 33.f, -11.f, 37.f, -8.f, 44.f, -11.f, 45.f, -11.f, 49.f, -8.f, 55.f, -0.f, 59.f, -10.f, 70.f, -13.f, 77.f, -10.f, 82.f, -10.f, 90.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 30.f, -0.f, - 1.f, -12.f, 12.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -9.f, 51.f, -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -0.f, - 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -0.f, 44.f, -10.f, 55.f, -13.f, 62.f, -10.f, 67.f, -10.f, 75.f, -0.f, + 1.f, -12.f, 12.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 41.f, -9.f, 52.f, -9.f, 62.f, -9.f, 68.f, -13.f, 71.f, -13.f, 80.f, -0.f, + 0.f, -13.f, 10.f, -9.f, 18.f, -9.f, 30.f, -9.f, 39.f, -0.f, 45.f, -10.f, 56.f, -13.f, 63.f, -10.f, 68.f, -10.f, 76.f, -0.f, 1.f, -10.f, 9.f, -10.f, 14.f, -13.f, 22.f, -10.f, 32.f, -2.f, 35.f, -11.f, 1.f, -10.f, 12.f, -13.f, 19.f, -10.f, 24.f, -10.f, 32.f, -0.f, 37.f, -10.f, 45.f, -10.f, 50.f, -13.f, 58.f, -10.f, 66.f, -0.f, - 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 38.f, -9.f, 49.f, -9.f, 59.f, -9.f, 65.f, -13.f, 68.f, -13.f, 77.f, -0.f, + 1.f, -13.f, 10.f, -9.f, 18.f, -13.f, 22.f, -13.f, 25.f, -9.f, 34.f, -0.f, 39.f, -9.f, 50.f, -9.f, 60.f, -9.f, 66.f, -13.f, 69.f, -13.f, 78.f, -0.f, 0.f, -8.f, 7.f, -6.f, 12.f, -7.f, 18.f, -7.f, 23.f, -11.f, 25.f, -0.f, 27.f, -7.f, 32.f, -11.f, 33.f, -11.f, 37.f, -8.f, 44.f, -11.f, 45.f, -11.f, 49.f, -8.f, 55.f, -0.f, }; struct LineRun line01 = @@ -2769,7 +2769,7 @@ int UtcDaliTextUpdateLayout03(void) 92.f, 15.f, -5.f, - 4.f, + 5.f, 0.f, false, false @@ -2814,10 +2814,10 @@ int UtcDaliTextUpdateLayout03(void) { { 74u, 12u }, { 74u, 12u }, - 79.f, + 80.f, 15.f, -5.f, - 3.f, + 4.f, 0.f, false, false @@ -2838,10 +2838,10 @@ int UtcDaliTextUpdateLayout03(void) { { 92u, 12u }, { 92u, 12u }, - 78.f, + 79.f, 15.f, -5.f, - 4.f, + 5.f, 0.f, false, false @@ -2874,10 +2874,10 @@ int UtcDaliTextUpdateLayout03(void) { { 128u, 12u }, { 128u, 12u }, - 81.f, + 82.f, 15.f, -5.f, - 3.f, + 4.f, 0.f, false, false @@ -2886,7 +2886,7 @@ int UtcDaliTextUpdateLayout03(void) { { 140u, 10u }, { 140u, 10u }, - 76.f, + 77.f, 15.f, -5.f, 4.f, @@ -2922,7 +2922,7 @@ int UtcDaliTextUpdateLayout03(void) { { 166u, 12u }, { 166u, 12u }, - 79.f, + 80.f, 15.f, -5.f, 4.f, @@ -2954,6 +2954,7 @@ int UtcDaliTextUpdateLayout03(void) false, false }; + Vector lines; lines.PushBack( line01 ); lines.PushBack( line02 ); diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp index eea51a6..db59db3 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp @@ -37,6 +37,7 @@ using namespace Text; // // void MergeFontDescriptions( const Vector& fontDescriptions, // Vector& fontIds, +// Vector& isDefaultFont, // const TextAbstraction::FontDescription& defaultFontDescription, // TextAbstraction::PointSize26Dot6 defaultPointSize, // CharacterIndex startIndex, @@ -79,6 +80,7 @@ struct MergeFontDescriptionsData unsigned int startIndex; ///< The start index. unsigned int numberOfCharacters; ///< The number of characters. Vector expectedFontIds; ///< The expected font ids. + Vector expectedIsDefault; ///< The expected font ids. }; struct ScriptsData @@ -108,9 +110,12 @@ bool MergeFontDescriptionsTest( const MergeFontDescriptionsData& data ) { Vector fontIds; fontIds.Resize( data.startIndex + data.numberOfCharacters, 0u ); + Vector isDefaultFont; + isDefaultFont.Resize( data.startIndex + data.numberOfCharacters, true ); MergeFontDescriptions( data.fontDescriptionRuns, fontIds, + isDefaultFont, data.defaultFontDescription, data.defaultPointSize, data.startIndex, @@ -141,6 +146,12 @@ bool MergeFontDescriptionsTest( const MergeFontDescriptionsData& data ) std::cout << std::endl; return false; } + + if( isDefaultFont[index] != data.expectedIsDefault[index] ) + { + std::cout << data.description << " Different 'is font default' at index : " << index << ", is font default : " << isDefaultFont[index] << ", expected : " << data.expectedIsDefault[index] << std::endl; + return false; + } } return true; @@ -413,12 +424,16 @@ int UtcDaliTextMergeFontDescriptions(void) TextAbstraction::FontDescription defaultFontDescription01; Vector fontDescriptionRuns01; Vector expectedFontIds01; + Vector expectedIsFontDefault01; TextAbstraction::FontDescription defaultFontDescription02; Vector fontDescriptionRuns02; Vector expectedFontIds02; expectedFontIds02.PushBack( 0u ); expectedFontIds02.PushBack( 0u ); + Vector expectedIsFontDefault02; + expectedIsFontDefault02.PushBack( true ); + expectedIsFontDefault02.PushBack( true ); TextAbstraction::FontDescription defaultFontDescription03; defaultFontDescription03.family = "DejaVu Serif"; @@ -532,6 +547,17 @@ int UtcDaliTextMergeFontDescriptions(void) expectedFontIds03.PushBack( 3u ); expectedFontIds03.PushBack( 6u ); expectedFontIds03.PushBack( 6u ); + Vector expectedIsFontDefault03; + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); + expectedIsFontDefault03.PushBack( false ); const MergeFontDescriptionsData data[] = { @@ -542,7 +568,8 @@ int UtcDaliTextMergeFontDescriptions(void) TextAbstraction::FontClient::DEFAULT_POINT_SIZE, 0u, 0u, - expectedFontIds01 + expectedFontIds01, + expectedIsFontDefault01 }, { "No description runs.", @@ -551,7 +578,8 @@ int UtcDaliTextMergeFontDescriptions(void) TextAbstraction::FontClient::DEFAULT_POINT_SIZE, 0u, 2u, - expectedFontIds02 + expectedFontIds02, + expectedIsFontDefault02 }, { "Some description runs.", @@ -560,7 +588,8 @@ int UtcDaliTextMergeFontDescriptions(void) TextAbstraction::FontClient::DEFAULT_POINT_SIZE, 0u, 10u, - expectedFontIds03 + expectedFontIds03, + expectedIsFontDefault03 } }; const unsigned int numberOfTests = 3u; diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index b9921c2..dcfb3e4 100644 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -53,9 +53,10 @@ Script LogicalModel::GetScript( CharacterIndex characterIndex ) const { // If this operation is too slow, consider a binary search. + const ScriptRun* const scriptRunBuffer = mScriptRuns.Begin(); for( Length index = 0u, length = mScriptRuns.Count(); index < length; ++index ) { - const ScriptRun* const scriptRun = mScriptRuns.Begin() + index; + const ScriptRun* const scriptRun = scriptRunBuffer + index; if( ( scriptRun->characterRun.characterIndex <= characterIndex ) && ( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) ) diff --git a/dali-toolkit/internal/text/multi-language-helper-functions.cpp b/dali-toolkit/internal/text/multi-language-helper-functions.cpp index 06b0f10..731b89d 100644 --- a/dali-toolkit/internal/text/multi-language-helper-functions.cpp +++ b/dali-toolkit/internal/text/multi-language-helper-functions.cpp @@ -32,6 +32,7 @@ namespace Text void MergeFontDescriptions( const Vector& fontDescriptions, Vector& fontIds, + Vector& isDefaultFont, const TextAbstraction::FontDescription& defaultFontDescription, TextAbstraction::PointSize26Dot6 defaultPointSize, CharacterIndex startIndex, @@ -43,6 +44,9 @@ void MergeFontDescriptions( const Vector& fontDescriptions, // Pointer to the font id buffer. FontId* fontIdsBuffer = fontIds.Begin(); + // Pointer to the 'is default' font buffer. + bool* isDefaultFontBuffer = isDefaultFont.Begin(); + // Used to temporarily store the style per character. TextAbstraction::FontDescription fontDescription; TextAbstraction::PointSize26Dot6 fontSize; @@ -57,7 +61,7 @@ void MergeFontDescriptions( const Vector& fontDescriptions, const CharacterIndex lastCharacterPlusOne = startIndex + numberOfCharacters; for( CharacterIndex index = startIndex; index < lastCharacterPlusOne; ++index ) { - bool defaultFont = true; + bool& defaultFont = *(isDefaultFontBuffer + index - startIndex ); Length runIndex = 0u; diff --git a/dali-toolkit/internal/text/multi-language-helper-functions.h b/dali-toolkit/internal/text/multi-language-helper-functions.h index b73da2f..8052638 100644 --- a/dali-toolkit/internal/text/multi-language-helper-functions.h +++ b/dali-toolkit/internal/text/multi-language-helper-functions.h @@ -39,6 +39,7 @@ namespace Text * * @param[in] fontDescriptions The font descriptions. * @param[out] fontIds The font id for each character. + * @param[out] isDefaultFont Whether the font is a default one. * @param[in] defaultFontDescription The default font description. * @param[in] defaultPointSize The default font size. * @param[in] startIndex The character from where the fonts are merged. @@ -46,6 +47,7 @@ namespace Text */ void MergeFontDescriptions( const Vector& fontDescriptions, Vector& fontIds, + Vector& isDefaultFont, const TextAbstraction::FontDescription& defaultFontDescription, TextAbstraction::PointSize26Dot6 defaultPointSize, CharacterIndex startIndex, diff --git a/dali-toolkit/internal/text/multi-language-support-impl.cpp b/dali-toolkit/internal/text/multi-language-support-impl.cpp index ec9167b..1e8abf2 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.cpp +++ b/dali-toolkit/internal/text/multi-language-support-impl.cpp @@ -47,7 +47,7 @@ namespace Text namespace Internal { -bool ValidateFontsPerScript::FindValidFont( FontId fontId ) const +bool ValidateFontsPerScript::IsValidFont( FontId fontId ) const { for( Vector::ConstIterator it = mValidFonts.Begin(), endIt = mValidFonts.End(); @@ -186,7 +186,7 @@ void MultilanguageSupport::SetScripts( const Vector& text, // Count the number of characters which are valid for all scripts. i.e. white spaces or '\n'. Length numberOfAllScriptCharacters = 0u; - // Pointers to the text and break info buffers. + // Pointers to the text buffer. const Character* const textBuffer = text.Begin(); // Traverse all characters and set the scripts. @@ -238,7 +238,7 @@ void MultilanguageSupport::SetScripts( const Vector& text, currentScriptRun.characterRun.numberOfCharacters = 0u; currentScriptRun.script = TextAbstraction::UNKNOWN; numberOfAllScriptCharacters = 0u; - } + } // Get the next character. ++index; @@ -415,8 +415,11 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // Merge font descriptions Vector fontIds; fontIds.Resize( numberOfCharacters, defaultFontId ); + Vector isDefaultFont; + isDefaultFont.Resize( numberOfCharacters, true ); MergeFontDescriptions( fontDescriptions, fontIds, + isDefaultFont, defaultFontDescription, defaultPointSize, startIndex, @@ -424,26 +427,35 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, const Character* const textBuffer = text.Begin(); const FontId* const fontIdsBuffer = fontIds.Begin(); + const bool* const isDefaultFontBuffer = isDefaultFont.Begin(); Vector::ConstIterator scriptRunIt = scripts.Begin(); Vector::ConstIterator scriptRunEndIt = scripts.End(); bool isNewParagraphCharacter = false; PointSize26Dot6 currentPointSize = defaultPointSize; FontId currentFontId = 0u; + FontId previousFontId = 0u; + + // Whether it's the first set of characters to be validated. + // Used in case the paragraph starts with characters common to all scripts. + bool isFirstSetToBeValidated = true; CharacterIndex lastCharacter = startIndex + numberOfCharacters; for( Length index = startIndex; index < lastCharacter; ++index ) { - // Get the character. + // Get the current character. const Character character = *( textBuffer + index ); - // Get the font for the character. + // Get the font for the current character. FontId fontId = *( fontIdsBuffer + index - startIndex ); - // Get the script for the character. - Script script = GetScript( index, - scriptRunIt, - scriptRunEndIt ); + // Whether the font being validated for the current character is a default one not set by the user. + const bool isDefault = *( isDefaultFontBuffer + index - startIndex ); + + // Get the script for the current character. + const Script script = GetScript( index, + scriptRunIt, + scriptRunEndIt ); // Get the current point size. if( currentFontId != fontId ) @@ -466,12 +478,10 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, } #endif - // Whether the font being validated is a default one not set by the user. - FontId preferredFont = fontId; - - // Validate if the font set by the user supports the character. + // Validate whether the current character is supported by the given font. + bool isValidFont = false; - // Check first in the caches. + // Check first in the cache of default fonts per script and size. DefaultFonts* defaultFonts = *( defaultFontPerScriptCacheBuffer + script ); FontId cachedDefaultFontId = 0u; @@ -480,112 +490,136 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, cachedDefaultFontId = defaultFonts->FindFont( fontClient, currentPointSize ); } - // The user may have set the default font. Check it. Otherwise check in the valid fonts cache. - if( fontId != cachedDefaultFontId ) - { - // Check in the valid fonts cache. - ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script ); + // Whether the cached default font is valid. + const bool isValidCachedDefaultFont = 0u != cachedDefaultFontId; - if( NULL == validateFontsPerScript ) - { - validateFontsPerScript = new ValidateFontsPerScript(); + // The font is valid if it matches with the default one for the current script and size and it's different than zero. + isValidFont = isValidCachedDefaultFont && ( fontId == cachedDefaultFontId ); - *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript; - } + bool isCommonScript = false; + + // If the given font is not valid, it means either: + // - there is no cached font for the current script yet or, + // - the user has set a different font than the default one for the current script or, + // - the platform default font is different than the default font for the current script. - if( NULL != validateFontsPerScript ) + // Need to check if the given font supports the current character. + if( !isValidFont ) // (1) + { + // Whether the current character is common for all scripts (i.e. white spaces, ...) + + // Is not desirable to cache fonts for the common script. + // + // i.e. Consider the text " हिंदी", the 'white space' has assigned the DEVANAGARI script. + // The user may have set a font or the platform's default is used. + // + // As the 'white space' is the first character, no font is cached so the font validation + // retrieves a glyph from the given font. + // + // Many fonts support 'white spaces' so probably the font set by the user or the platform's default + // supports the 'white space'. However, that font may not support the DEVANAGARI script. + isCommonScript = TextAbstraction::IsCommonScript( character ); + + if( isCommonScript ) + { + if( isValidCachedDefaultFont && + ( isDefault || ( currentFontId == previousFontId ) ) ) + { + // At this point the character common for all scripts has no font assigned. + // If there is a valid previously cached default font for it, use that one. + fontId = cachedDefaultFontId; + isValidFont = true; + } + } + else { - if( !validateFontsPerScript->FindValidFont( fontId ) ) + // Check in the valid fonts cache. + ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script ); + + if( NULL != validateFontsPerScript ) + { + isValidFont = validateFontsPerScript->IsValidFont( fontId ); + } + + if( !isValidFont ) // (2) { // Use the font client to validate the font. - GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character ); + const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character ); + + // The font is valid if there is a glyph for that character. + isValidFont = 0u != glyphIndex; // Emojis are present in many monochrome fonts; prefer color by default. - if( ( TextAbstraction::EMOJI == script ) && - ( 0u != glyphIndex ) ) + if( isValidFont && + ( TextAbstraction::EMOJI == script ) ) { - BufferImage bitmap = fontClient.CreateBitmap( fontId, glyphIndex ); - if( bitmap && - ( Pixel::BGRA8888 != bitmap.GetPixelFormat() ) ) - { - glyphIndex = 0u; - } - } + const BufferImage bitmap = fontClient.CreateBitmap( fontId, glyphIndex ); - if( 0u == glyphIndex ) - { - // The font is not valid. Set to zero and a default one will be set. - fontId = 0u; + // For color emojis, the font is valid if the bitmap is RGBA. + isValidFont = bitmap && ( Pixel::BGRA8888 == bitmap.GetPixelFormat() ); } - else + + // If there is a valid font, cache it. + if( isValidFont ) { - // Add the font to the valid font cache. - - // At this point the validated font supports the given character. However, characters - // common for all scripts, like white spaces or new paragraph characters, need to be - // processed differently. - // - // i.e. A white space can have assigned a DEVANAGARI script but the font assigned may not - // support none of the DEVANAGARI glyphs. This font can't be added to the cache as a valid - // font for the DEVANAGARI script but the COMMON one. - if( TextAbstraction::IsCommonScript( character ) ) + if( NULL == validateFontsPerScript ) { - validateFontsPerScript = *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON ); + validateFontsPerScript = new ValidateFontsPerScript(); - if( NULL == validateFontsPerScript ) - { - validateFontsPerScript = new ValidateFontsPerScript(); - - *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON ) = validateFontsPerScript; - } + *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript; } validateFontsPerScript->mValidFonts.PushBack( fontId ); } - } - } - } - // The font has not been validated. Find a default one. - if( 0u == fontId ) - { - // The character has no font assigned. Get a default one from the cache - fontId = cachedDefaultFontId; + if( !isValidFont ) // (3) + { + // The given font has not been validated. - // If the cache has not a default font, get one from the font client. - if( 0u == fontId ) - { - // Emojis are present in many monochrome fonts; prefer color by default. - bool preferColor = ( TextAbstraction::EMOJI == script ); + if( isValidCachedDefaultFont ) + { + // Use the cached default font for the script if there is one. + fontId = cachedDefaultFontId; + } + else + { + // There is no valid cached default font for the script. - // Find a fallback-font. - fontId = fontClient.FindFallbackFont( preferredFont, character, currentPointSize, preferColor ); + DefaultFonts* defaultFontsPerScript = NULL; - // If the system does not support a suitable font, fallback to Latin - DefaultFonts* latinDefaults = NULL; - if( 0u == fontId ) - { - latinDefaults = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN ); - if( NULL != latinDefaults ) - { - fontId = latinDefaults->FindFont( fontClient, currentPointSize ); - } - } + // Emojis are present in many monochrome fonts; prefer color by default. + const bool preferColor = ( TextAbstraction::EMOJI == script ); - if( 0u == fontId ) - { - fontId = fontClient.FindDefaultFont( UTF32_A, currentPointSize ); - } + // Find a fallback-font. + fontId = fontClient.FindFallbackFont( currentFontId, character, currentPointSize, preferColor ); - // Cache the font. - if( NULL == latinDefaults ) - { - latinDefaults = new DefaultFonts(); - *( defaultFontPerScriptCacheBuffer + script ) = latinDefaults; - } - latinDefaults->mFonts.PushBack( fontId ); - } - } + if( 0u == fontId ) + { + // If the system does not support a suitable font, fallback to Latin + defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN ); + if( NULL != defaultFontsPerScript ) + { + fontId = defaultFontsPerScript->FindFont( fontClient, currentPointSize ); + } + } + + if( 0u == fontId ) + { + fontId = fontClient.FindDefaultFont( UTF32_A, currentPointSize ); + } + + // Cache the font. + if( NULL == defaultFontsPerScript ) + { + defaultFontsPerScript = new DefaultFonts(); + *( defaultFontPerScriptCacheBuffer + script ) = defaultFontsPerScript; + } + defaultFontsPerScript->mFonts.PushBack( fontId ); + } + } // !isValidFont (3) + } // !isValidFont (2) + } // !isCommonScript + } // !isValidFont (1) #ifdef DEBUG_ENABLED { @@ -600,6 +634,12 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, } #endif + if( isFirstSetToBeValidated && !isCommonScript ) + { + currentFontRun.fontId = fontId; + isFirstSetToBeValidated = false; + } + // The font is now validated. if( ( fontId != currentFontRun.fontId ) || isNewParagraphCharacter ) @@ -617,6 +657,11 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters; currentFontRun.characterRun.numberOfCharacters = 0u; currentFontRun.fontId = fontId; + + if( isNewParagraphCharacter ) + { + isFirstSetToBeValidated = true; + } } // Add one more character to the run. @@ -624,7 +669,8 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // Whether the current character is a new paragraph character. isNewParagraphCharacter = TextAbstraction::IsNewParagraph( character ); - } + previousFontId = currentFontId; + } // end traverse characters. if( 0u != currentFontRun.characterRun.numberOfCharacters ) { diff --git a/dali-toolkit/internal/text/multi-language-support-impl.h b/dali-toolkit/internal/text/multi-language-support-impl.h index 283b021..ff5e94d 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.h +++ b/dali-toolkit/internal/text/multi-language-support-impl.h @@ -67,7 +67,7 @@ struct ValidateFontsPerScript * * @return @e true if the font is in the vector of valid fonts. */ - bool FindValidFont( FontId fontId ) const; + bool IsValidFont( FontId fontId ) const; Vector mValidFonts; }; -- 2.7.4