1 #ifndef __TEXTLANG_H_INCLUDED__
2 #define __TEXTLANG_H_INCLUDED__
3 
4 #include "crsetup.h"
5 #include "lvptrvec.h"
6 #include "lvstring.h"
7 
8 #if USE_HARFBUZZ==1
9 #include <hb.h>
10 #include <hb-ft.h>
11 #endif
12 
13 #if USE_LIBUNIBREAK==1
14     #ifdef __cplusplus
15     extern "C" {
16     #endif
17 #include <linebreak.h>
18 #include <linebreakdef.h>
19     #ifdef __cplusplus
20     }
21     #endif
22 #endif
23 
24 // Be similar to HyphMan default state with "English_US.pattern"
25 #define TEXTLANG_DEFAULT_MAIN_LANG              "en"   // for LVDocView
26 #define TEXTLANG_DEFAULT_MAIN_LANG_32           U"en"  // for textlang.cpp
27 #define TEXTLANG_DEFAULT_EMBEDDED_LANGS_ENABLED false
28 #define TEXTLANG_DEFAULT_HYPHENATION_ENABLED    true
29 #define TEXTLANG_DEFAULT_HYPH_SOFT_HYPHENS_ONLY false
30 #define TEXTLANG_DEFAULT_HYPH_FORCE_ALGORITHMIC false
31 #define TEXTLANG_FALLBACK_HYPH_DICT_ID  U"English_US.pattern" // For languages without specific hyph dicts
32 
33 class TextLangCfg;
34 class HyphMethod;
35 struct ldomNode;
36 
37 class TextLangMan
38 {
39     friend class TextLangCfg;
40     static lString32 _main_lang;
41     static bool _embedded_langs_enabled;
42     static LVPtrVector<TextLangCfg> _lang_cfg_list;
43 
44     static bool _overridden_hyph_method; // (to avoid checking the 3 following bool)
45     static bool _hyphenation_enabled;
46     static bool _hyphenation_soft_hyphens_only;
47     static bool _hyphenation_force_algorithmic;
48     static HyphMethod * _no_hyph_method;       // instance of hyphman NoHyph
49     static HyphMethod * _soft_hyphens_method;  // instance of hyphman SoftHyphensHyph
50     static HyphMethod * _algo_hyph_method;     // instance of hyphman AlgoHyph
51 
52     static HyphMethod * getHyphMethodForLang( lString32 lang_tag ); // Used by TextLangCfg
53 public:
54     static void uninit();
55     static lUInt32 getHash();
56 
setMainLang(lString32 lang_tag)57     static void setMainLang( lString32 lang_tag ) { _main_lang = lang_tag; }
58     static void setMainLangFromHyphDict( lString32 id ); // For HyphMan legacy methods
getMainLang()59     static lString32 getMainLang() { return _main_lang; }
60 
setEmbeddedLangsEnabled(bool enabled)61     static void setEmbeddedLangsEnabled( bool enabled ) { _embedded_langs_enabled = enabled; }
getEmbeddedLangsEnabled()62     static bool getEmbeddedLangsEnabled() { return _embedded_langs_enabled; }
63 
getHyphenationEnabled()64     static bool getHyphenationEnabled() { return _hyphenation_enabled; }
setHyphenationEnabled(bool enabled)65     static void setHyphenationEnabled( bool enabled ) {
66         _hyphenation_enabled = enabled;
67         _overridden_hyph_method = !_hyphenation_enabled || _hyphenation_soft_hyphens_only || _hyphenation_force_algorithmic;
68     }
69 
getHyphenationSoftHyphensOnly()70     static bool getHyphenationSoftHyphensOnly() { return _hyphenation_soft_hyphens_only; }
setHyphenationSoftHyphensOnly(bool enabled)71     static void setHyphenationSoftHyphensOnly( bool enabled ) {
72         _hyphenation_soft_hyphens_only = enabled;
73         _overridden_hyph_method = !_hyphenation_enabled || _hyphenation_soft_hyphens_only || _hyphenation_force_algorithmic;
74     }
75 
getHyphenationForceAlgorithmic()76     static bool getHyphenationForceAlgorithmic() { return _hyphenation_force_algorithmic; }
setHyphenationForceAlgorithmic(bool enabled)77     static void setHyphenationForceAlgorithmic( bool enabled ) {
78         _hyphenation_force_algorithmic = enabled;
79         _overridden_hyph_method = !_hyphenation_enabled || _hyphenation_soft_hyphens_only || _hyphenation_force_algorithmic;
80     }
81 
82     static TextLangCfg * getTextLangCfg(); // get LangCfg for _main_lang
83     static TextLangCfg * getTextLangCfg( lString32 lang_tag );
84     static TextLangCfg * getTextLangCfg( ldomNode * node );
85     static int getLangNodeIndex( ldomNode * node );
86 
87     static HyphMethod * getMainLangHyphMethod(); // For HyphMan::hyphenate()
88 
89     static void resetCounters();
90 
91     // For frontend info about TextLangMan status and seen langs
getLangCfgList()92     static LVPtrVector<TextLangCfg> * getLangCfgList() {
93         return &_lang_cfg_list;
94     }
95 
96     static lString32 getLangTag(const lString32& title);
97 
98     TextLangMan();
99     ~TextLangMan();
100 };
101 
102 #define MAX_NB_LB_PROPS_ITEMS 20 // for our statically sized array (increase if needed)
103 
104 #if USE_LIBUNIBREAK==1
105 typedef lChar32 (*lb_char_sub_func_t)(struct LineBreakContext *lbpCtx, const lChar32 * text, int pos, int next_usable);
106 #endif
107 
108 class TextLangCfg
109 {
110     friend class TextLangMan;
111     lString32 _lang_tag;
112     HyphMethod * _hyph_method;
113 
114     lString32 _open_quote1;
115     lString32 _close_quote1;
116     lString32 _open_quote2;
117     lString32 _close_quote2;
118     int _quote_nesting_level;
119 
120     #if USE_HARFBUZZ==1
121     hb_language_t _hb_language;
122     #endif
123 
124     #if USE_LIBUNIBREAK==1
125     lb_char_sub_func_t _lb_char_sub_func;
126     struct LineBreakProperties _lb_props[MAX_NB_LB_PROPS_ITEMS];
127     #endif
128 
129     bool _duplicate_real_hyphen_on_next_line;
130 
131     void resetCounters();
132 
133 public:
getLangTag()134     lString32 getLangTag() const { return _lang_tag; }
135 
getHyphMethod()136     HyphMethod * getHyphMethod() const {
137         if ( !TextLangMan::_overridden_hyph_method )
138             return _hyph_method;
139         if ( !TextLangMan::_hyphenation_enabled )
140             return TextLangMan::_no_hyph_method;
141         if ( TextLangMan::_hyphenation_soft_hyphens_only )
142             return TextLangMan::_soft_hyphens_method;
143         if ( TextLangMan::_hyphenation_force_algorithmic )
144             return TextLangMan::_algo_hyph_method;
145         // Should not be reached
146         return _hyph_method;
147     }
getDefaultHyphMethod()148     HyphMethod * getDefaultHyphMethod() const {
149         return _hyph_method;
150     }
151 
152     lString32 & getOpeningQuote( bool update_level=true );
153     lString32 & getClosingQuote( bool update_level=true );
154 
155     int getHyphenHangingPercent();
156     int getHangingPercent( bool right_hanging, bool & check_font, const lChar32 * text, int pos, int next_usable );
157 
158     #if USE_HARFBUZZ==1
getHBLanguage()159     hb_language_t getHBLanguage() const { return _hb_language; }
160     #endif
161 
162     #if USE_LIBUNIBREAK==1
hasLBCharSubFunc()163     bool hasLBCharSubFunc() const { return _lb_char_sub_func != NULL; }
getLBCharSubFunc()164     lb_char_sub_func_t getLBCharSubFunc() const { return _lb_char_sub_func; }
getLBProps()165     struct LineBreakProperties * getLBProps() const { return (struct LineBreakProperties *)_lb_props; }
166     #endif
167 
duplicateRealHyphenOnNextLine()168     bool duplicateRealHyphenOnNextLine() const { return _duplicate_real_hyphen_on_next_line; }
169 
170     TextLangCfg( lString32 lang_tag );
171     ~TextLangCfg();
172 };
173 
174 
175 #endif
176