From 50c2178137e3968835dc1b7fa4731d9a55bd7de0 Mon Sep 17 00:00:00 2001 From: bbshelper Date: Wed, 26 Jun 2024 09:44:22 +0800 Subject: [PATCH 1/3] text: optimize tab handling Find first tab as needed, and don't check beyond marker width. --- crengine/src/lvtextfm.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/crengine/src/lvtextfm.cpp b/crengine/src/lvtextfm.cpp index 72ada9fa5..aa194b3c2 100644 --- a/crengine/src/lvtextfm.cpp +++ b/crengine/src/lvtextfm.cpp @@ -1845,7 +1845,6 @@ class LVFormatter { #define MAX_TEXT_CHUNK_SIZE 4096 static lUInt16 widths[MAX_TEXT_CHUNK_SIZE+1]; static lUInt8 flags[MAX_TEXT_CHUNK_SIZE+1]; - int tabIndex = -1; #if (USE_FRIBIDI==1) FriBidiLevel lastBidiLevel = 0; FriBidiLevel newBidiLevel; @@ -1864,9 +1863,6 @@ class LVFormatter { LVFont * newFont = NULL; lInt16 newLetterSpacing = 0; src_text_fragment_t * newSrc = NULL; - if ( tabIndex<0 && m_text[i]=='\t' ) { - tabIndex = i; - } bool isObject = false; bool prevCharIsObject = false; if ( i= 0 && m_srcs[0]->indent < 0) { + if (m_srcs[0] && m_srcs[0]->indent < 0) { // Used by obsolete rendering of css_d_list_item_legacy when css_lsp_outside, // where the marker width is provided as negative/hanging indent. int tabPosition = -m_srcs[0]->indent; // has been set to marker_width - if ( tabPosition>0 && tabPosition > m_widths[tabIndex] ) { - int dx = tabPosition - m_widths[tabIndex]; - for ( i=tabIndex; i= tabPosition; ++j) { + if (m_text[j] == '\t') { + int dx = tabPosition - m_widths[j]; + for ( int i=j; i Date: Wed, 26 Jun 2024 14:13:51 +0800 Subject: [PATCH 2/3] text: optimize measureText()'s bidi handling Calculate bidi direction on measuring, not on every char. --- crengine/src/lvtextfm.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/crengine/src/lvtextfm.cpp b/crengine/src/lvtextfm.cpp index aa194b3c2..5be2d531f 100644 --- a/crengine/src/lvtextfm.cpp +++ b/crengine/src/lvtextfm.cpp @@ -1900,17 +1900,13 @@ class LVFormatter { } #endif bool bidiLevelChanged = false; - int lastDirection = 0; // unknown #if (USE_FRIBIDI==1) - lastDirection = 1; // direction known: LTR if no bidi found if (m_has_bidi) { newBidiLevel = m_bidi_levels[i]; if (i == 0) lastBidiLevel = newBidiLevel; else if ( newBidiLevel != lastBidiLevel ) bidiLevelChanged = true; - if ( FRIBIDI_LEVEL_IS_RTL(lastBidiLevel) ) - lastDirection = -1; // RTL } #endif // When measuring with Harfbuzz, we should also split on Unicode script change, @@ -1972,11 +1968,13 @@ class LVFormatter { lUInt32 hints = 0; if ( start == 0 ) hints |= LFNT_HINT_BEGINS_PARAGRAPH; if ( i == m_length ) hints |= LFNT_HINT_ENDS_PARAGRAPH; - if ( lastDirection ) { - hints |= LFNT_HINT_DIRECTION_KNOWN; - if ( lastDirection < 0 ) - hints |= LFNT_HINT_DIRECTION_IS_RTL; - } + #if (USE_FRIBIDI==1) + if (m_has_bidi) { + hints |= LFNT_HINT_DIRECTION_KNOWN; + if (FRIBIDI_LEVEL_IS_RTL(lastBidiLevel)) + hints |= LFNT_HINT_DIRECTION_IS_RTL; + } + #endif int chars_measured = lastFont->measureText( m_text + start, len, @@ -2302,7 +2300,7 @@ class LVFormatter { // (In the context of inline elements, margin/border/padding-inline-start/end // would be more natural to use than -left/right - but it's a more recent CSS // addition that we don't support.) - bool is_mirrored = lastDirection < 0; + bool is_mirrored = FRIBIDI_LEVEL_IS_RTL(lastBidiLevel); if ( is_right_pad != is_mirrored ) { // unmirrored right pad, or mirrored left pad // Use right margin/border/padding values margin = lengthToPx( node, style->margin[1], base_width ); From e391bbb1e538c7d10d76be222bb2240cffbce7cd Mon Sep 17 00:00:00 2001 From: bbshelper Date: Wed, 26 Jun 2024 14:20:22 +0800 Subject: [PATCH 3/3] text: simplify measureText()'s harfbuzz check It doesn't seem to be necessary to set usingHarfbuzz on the first font met: the variable doesn't change, and when it's checked, there is always a valid font. --- crengine/src/lvtextfm.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/crengine/src/lvtextfm.cpp b/crengine/src/lvtextfm.cpp index 5be2d531f..00124b6de 100644 --- a/crengine/src/lvtextfm.cpp +++ b/crengine/src/lvtextfm.cpp @@ -1850,8 +1850,7 @@ class LVFormatter { FriBidiLevel newBidiLevel; #endif #if (USE_HARFBUZZ==1) - bool checkIfHarfbuzz = true; - bool usingHarfbuzz = false; + bool usingHarfbuzz = m_kerning_mode == KERNING_MODE_HARFBUZZ; // Unicode script change (note: hb_script_t is uint32_t) lUInt32 prevScript = HB_SCRIPT_COMMON; hb_unicode_funcs_t* _hb_unicode_funcs = hb_unicode_funcs_get_default(); @@ -1870,15 +1869,6 @@ class LVFormatter { isObject = m_flags[i] & LCHAR_IS_OBJECT; // image, float or inline box newFont = isObject ? NULL : (LVFont *)newSrc->t.font; newLetterSpacing = newSrc->letter_spacing; // 0 for objects - #if (USE_HARFBUZZ==1) - // Check if we are using Harfbuzz kerning with the first font met - if ( checkIfHarfbuzz && newFont ) { - if ( m_kerning_mode == KERNING_MODE_HARFBUZZ ) { - usingHarfbuzz = true; - } - checkIfHarfbuzz = false; - } - #endif } if (i > 0) prevCharIsObject = m_flags[i-1] & LCHAR_IS_OBJECT; // image, float or inline box