1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #ifndef _SCRIPTINFO_HXX 24 #define _SCRIPTINFO_HXX 25 #ifndef _SVSTDARR_HXX 26 #define _SVSTDARR_SHORTS 27 #define _SVSTDARR_BYTES 28 #define _SVSTDARR_USHORTS 29 #define _SVSTDARR_XUB_STRLEN 30 #include <svl/svstdarr.hxx> 31 #endif 32 #include <i18npool/lang.h> 33 #include <list> 34 #include <modeltoviewhelper.hxx> 35 36 #include <errhdl.hxx> 37 38 class SwTxtNode; 39 class Point; 40 class MultiSelection; 41 class String; 42 typedef std::list< xub_StrLen > PositionList; 43 44 #define SPACING_PRECISION_FACTOR 100 45 46 /************************************************************************* 47 * class SwScanner 48 * Hilfsklasse, die beim Spellen die Worte im gewuenschten Bereich 49 * nacheinander zur Verfuegung stellt. 50 *************************************************************************/ 51 52 class SwScanner 53 { 54 XubString aWord; 55 const SwTxtNode& rNode; 56 const String& rText; 57 const LanguageType* pLanguage; 58 const ModelToViewHelper::ConversionMap* pConversionMap; 59 xub_StrLen nStartPos; 60 xub_StrLen nEndPos; 61 xub_StrLen nBegin; 62 xub_StrLen nLen; 63 LanguageType aCurrLang; 64 sal_uInt16 nWordType; 65 sal_Bool bClip; 66 67 public: 68 SwScanner( const SwTxtNode& rNd, const String& rTxt, const LanguageType* pLang, 69 const ModelToViewHelper::ConversionMap* pConvMap, 70 sal_uInt16 nWordType, 71 xub_StrLen nStart, xub_StrLen nEnde, sal_Bool bClip = sal_False ); 72 73 74 // This next word function tries to find the language for the next word 75 // It should currently _not_ be used for spell checking, and works only for 76 // ! bReverse 77 sal_Bool NextWord(); 78 79 const XubString& GetWord() const { return aWord; } 80 81 xub_StrLen GetBegin() const { return nBegin; } 82 xub_StrLen GetEnd() const { return nBegin + nLen; } 83 xub_StrLen GetLen() const { return nLen; } 84 85 LanguageType GetCurrentLanguage() const {return aCurrLang;} 86 }; 87 88 /************************************************************************* 89 * class SwScriptInfo 90 * 91 * encapsultes information about script changes 92 *************************************************************************/ 93 94 class SwScriptInfo 95 { 96 private: 97 SvXub_StrLens aScriptChg; 98 SvBytes aScriptType; 99 SvXub_StrLens aDirChg; 100 SvBytes aDirType; 101 SvXub_StrLens aKashida; 102 SvXub_StrLens aKashidaInvalid; 103 SvXub_StrLens aNoKashidaLine; 104 SvXub_StrLens aNoKashidaLineEnd; 105 SvXub_StrLens aCompChg; 106 SvXub_StrLens aCompLen; 107 SvXub_StrLens aHiddenChg; 108 SvBytes aCompType; 109 xub_StrLen nInvalidityPos; 110 sal_uInt8 nDefaultDir; 111 112 void UpdateBidiInfo( const String& rTxt ); 113 114 sal_Bool IsKashidaValid ( xub_StrLen nKashPos ) const; 115 void MarkKashidaInvalid ( xub_StrLen nKashPos ); 116 void ClearKashidaInvalid ( xub_StrLen nKashPos ); 117 bool MarkOrClearKashidaInvalid( xub_StrLen nStt, xub_StrLen nLen, bool bMark, xub_StrLen nMarkCount ); 118 bool IsKashidaLine ( xub_StrLen nCharIdx ) const; 119 120 public: 121 enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE }; 122 123 SwScriptInfo(); 124 ~SwScriptInfo(); 125 126 // determines script changes 127 void InitScriptInfo( const SwTxtNode& rNode, sal_Bool bRTL ); 128 void InitScriptInfo( const SwTxtNode& rNode ); 129 130 // set/get position from which data is invalid 131 inline void SetInvalidity( const xub_StrLen nPos ); 132 inline xub_StrLen GetInvalidity() const { return nInvalidityPos; }; 133 134 // get default direction for paragraph 135 inline sal_uInt8 GetDefaultDir() const { return nDefaultDir; }; 136 137 // array operations, nCnt refers to array position 138 inline size_t CountScriptChg() const; 139 inline xub_StrLen GetScriptChg( const size_t nCnt ) const; 140 inline sal_uInt8 GetScriptType( const sal_uInt16 nCnt ) const; 141 142 inline size_t CountDirChg() const; 143 inline xub_StrLen GetDirChg( const size_t nCnt ) const; 144 inline sal_uInt8 GetDirType( const size_t nCnt ) const; 145 146 inline size_t CountKashida() const; 147 inline xub_StrLen GetKashida( const size_t nCnt ) const; 148 149 inline size_t CountCompChg() const; 150 inline xub_StrLen GetCompStart( const size_t nCnt ) const; 151 inline xub_StrLen GetCompLen( const size_t nCnt ) const; 152 inline sal_uInt8 GetCompType( const size_t nCnt ) const; 153 154 inline size_t CountHiddenChg() const; 155 inline xub_StrLen GetHiddenChg( const size_t nCnt ) const; 156 static void CalcHiddenRanges( const SwTxtNode& rNode, 157 MultiSelection& rHiddenMulti ); 158 159 // "high" level operations, nPos refers to string position 160 xub_StrLen NextScriptChg( const xub_StrLen nPos ) const; 161 sal_uInt8 ScriptType( const xub_StrLen nPos ) const; 162 163 // Returns the position of the next direction level change. 164 // If bLevel is set, the position of the next level which is smaller 165 // than the level at position nPos is returned. This is required to 166 // obtain the end of a SwBidiPortion 167 xub_StrLen NextDirChg( const xub_StrLen nPos, 168 const sal_uInt8* pLevel = 0 ) const; 169 sal_uInt8 DirType( const xub_StrLen nPos ) const; 170 171 #if OSL_DEBUG_LEVEL > 1 172 sal_uInt8 CompType( const xub_StrLen nPos ) const; 173 #endif 174 175 // 176 // HIDDEN TEXT STUFF START 177 // 178 179 /** Hidden text range information - static and non-version 180 181 @descr Determines if a given position is inside a hidden text range. The 182 static version tries to obtain a valid SwScriptInfo object 183 via the SwTxtNode, otherwise it calculates the values from scratch. 184 The non-static version uses the internally cached informatio 185 for the calculation. 186 187 @param rNode 188 The text node. 189 @param nPos 190 The given position that should be checked. 191 @param rnStartPos 192 Return parameter for the start position of the hidden range. 193 STRING_LEN if nPos is not inside a hidden range. 194 @param rnEndPos 195 Return parameter for the end position of the hidden range. 196 0 if nPos is not inside a hidden range. 197 @param rnEndPos 198 Return parameter that contains all the hidden text ranges. Optional. 199 @return 200 returns true if there are any hidden characters in this paragraph. 201 202 */ 203 static bool GetBoundsOfHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos, 204 xub_StrLen& rnStartPos, xub_StrLen& rnEndPos, 205 PositionList* pList = 0 ); 206 bool GetBoundsOfHiddenRange( xub_StrLen nPos, xub_StrLen& rnStartPos, 207 xub_StrLen& rnEndPos, PositionList* pList = 0 ) const; 208 209 static bool IsInHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos ); 210 211 /** Hidden text attribute handling 212 213 @descr Takes a string and either deletes the hidden ranges or sets 214 a given character in place of the hidden characters. 215 216 @param rNode 217 The text node. 218 @param nPos 219 The string to modify. 220 @param cChar 221 The character that should replace the hidden characters. 222 @param bDel 223 If set, the hidden ranges will be deleted from the text node. 224 */ 225 static sal_uInt16 MaskHiddenRanges( const SwTxtNode& rNode, XubString& rText, 226 const xub_StrLen nStt, const xub_StrLen nEnd, 227 const xub_Unicode cChar ); 228 229 /** Hidden text attribute handling 230 231 @descr Takes a SwTxtNode and deletes the hidden ranges from the node. 232 233 @param rNode 234 The text node. 235 */ 236 static void DeleteHiddenRanges( SwTxtNode& rNode ); 237 238 // 239 // HIDDEN TEXT STUFF END 240 // 241 242 // examines the range [ nStart, nStart + nEnd ] if there are kanas 243 // returns start index of kana entry in array, otherwise USHRT_MAX 244 sal_uInt16 HasKana( xub_StrLen nStart, const xub_StrLen nEnd ) const; 245 246 // modifies the kerning array according to a given compress value 247 long Compress( sal_Int32* pKernArray, xub_StrLen nIdx, xub_StrLen nLen, 248 const sal_uInt16 nCompress, const sal_uInt16 nFontHeight, 249 Point* pPoint = NULL ) const; 250 251 /** Performes a kashida justification on the kerning array 252 253 @descr Add some extra space for kashida justification to the 254 positions in the kerning array. 255 @param pKernArray 256 The printers kerning array. Optional. 257 @param pScrArray 258 The screen kerning array. Optional. 259 @param nStt 260 Start referring to the paragraph. 261 @param nLen 262 The number of characters to be considered. 263 @param nSpaceAdd 264 The value which has to be added to a kashida opportunity. 265 @return The number of kashida opportunities in the given range 266 */ 267 sal_uInt16 KashidaJustify( sal_Int32* pKernArray, sal_Int32* pScrArray, 268 xub_StrLen nStt, xub_StrLen nLen, 269 long nSpaceAdd = 0) const; 270 271 /** Clears array of kashidas marked as invalid 272 */ 273 inline void ClearKashidaInvalid ( xub_StrLen nStt, xub_StrLen nLen ) { MarkOrClearKashidaInvalid( nStt, nLen, false, 0 ); } 274 275 /** Marks nCnt kashida positions as invalid 276 pKashidaPositions: array of char indices relative to the paragraph 277 */ 278 bool MarkKashidasInvalid ( xub_StrLen nCnt, xub_StrLen* pKashidaPositions ); 279 280 /** Marks nCnt kashida positions as invalid 281 in the given text range 282 */ 283 inline bool MarkKashidasInvalid ( xub_StrLen nCnt, xub_StrLen nStt, xub_StrLen nLen ) 284 { return MarkOrClearKashidaInvalid( nStt, nLen, true, nCnt ); } 285 286 /** retrieves kashida opportunities for a given text range. 287 returns the number of kashida positions in the given text range 288 289 pKashidaPositions: buffer to reveive the char indices of the 290 kashida opportunties relative to the paragraph 291 */ 292 sal_uInt16 GetKashidaPositions ( xub_StrLen nStt, xub_StrLen nLen, 293 xub_StrLen* pKashidaPosition ); 294 295 296 297 298 /** Use regular blank justification instead of kashdida justification for the given line of text. 299 nStt Start char index of the line referring to the paragraph. 300 nLen Number of characters in the line 301 */ 302 void SetNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen ); 303 304 /** Clear forced blank justification for a given line. 305 nStt Start char index of the line referring to the paragraph. 306 nLen Number of characters in the line 307 */ 308 void ClearNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen ); 309 310 /** Checks if text is Arabic text. 311 312 @descr Checks if text is Arabic text. 313 @param rTxt 314 The text to check 315 @param nStt 316 Start index of the text 317 @return Returns if the language is an Arabic language 318 */ 319 static sal_Bool IsArabicText( const XubString& rTxt, xub_StrLen nStt, xub_StrLen nLen ); 320 321 /** Performes a thai justification on the kerning array 322 323 @descr Add some extra space for thai justification to the 324 positions in the kerning array. 325 @param rTxt 326 The String 327 @param pKernArray 328 The printers kerning array. Optional. 329 @param pScrArray 330 The screen kerning array. Optional. 331 @param nIdx 332 Start referring to the paragraph. 333 @param nLen 334 The number of characters to be considered. 335 @param nSpaceAdd 336 The value which has to be added to the cells. 337 @return The number of extra spaces in the given range 338 */ 339 static sal_uInt16 ThaiJustify( const XubString& rTxt, sal_Int32* pKernArray, 340 sal_Int32* pScrArray, xub_StrLen nIdx, 341 xub_StrLen nLen, xub_StrLen nNumberOfBlanks = 0, 342 long nSpaceAdd = 0 ); 343 344 static SwScriptInfo* GetScriptInfo( const SwTxtNode& rNode, 345 sal_Bool bAllowInvalid = sal_False ); 346 347 static sal_uInt8 WhichFont( xub_StrLen nIdx, const String* pTxt, const SwScriptInfo* pSI ); 348 }; 349 350 inline void SwScriptInfo::SetInvalidity( const xub_StrLen nPos ) 351 { 352 if ( nPos < nInvalidityPos ) 353 nInvalidityPos = nPos; 354 }; 355 inline size_t SwScriptInfo::CountScriptChg() const { return aScriptChg.size(); } 356 inline xub_StrLen SwScriptInfo::GetScriptChg( const size_t nCnt ) const 357 { 358 ASSERT( nCnt < aScriptChg.size(),"No ScriptChange today!"); 359 return aScriptChg[ nCnt ]; 360 } 361 inline sal_uInt8 SwScriptInfo::GetScriptType( const xub_StrLen nCnt ) const 362 { 363 ASSERT( nCnt < aScriptType.size(),"No ScriptType today!"); 364 return aScriptType[ nCnt ]; 365 } 366 367 inline size_t SwScriptInfo::CountDirChg() const { return aDirChg.size(); } 368 inline xub_StrLen SwScriptInfo::GetDirChg( const size_t nCnt ) const 369 { 370 ASSERT( nCnt < aDirChg.size(),"No DirChange today!"); 371 return aDirChg[ nCnt ]; 372 } 373 inline sal_uInt8 SwScriptInfo::GetDirType( const size_t nCnt ) const 374 { 375 ASSERT( nCnt < aDirType.size(),"No DirType today!"); 376 return aDirType[ nCnt ]; 377 } 378 379 inline size_t SwScriptInfo::CountKashida() const { return aKashida.size(); } 380 inline xub_StrLen SwScriptInfo::GetKashida( const size_t nCnt ) const 381 { 382 ASSERT( nCnt < aKashida.size(),"No Kashidas today!"); 383 return aKashida[ nCnt ]; 384 } 385 386 inline size_t SwScriptInfo::CountCompChg() const { return aCompChg.size(); }; 387 inline xub_StrLen SwScriptInfo::GetCompStart( const size_t nCnt ) const 388 { 389 ASSERT( nCnt < aCompChg.size(),"No CompressionStart today!"); 390 return aCompChg[ nCnt ]; 391 } 392 inline xub_StrLen SwScriptInfo::GetCompLen( const size_t nCnt ) const 393 { 394 ASSERT( nCnt < aCompLen.size(),"No CompressionLen today!"); 395 return aCompLen[ nCnt ]; 396 } 397 398 inline sal_uInt8 SwScriptInfo::GetCompType( const size_t nCnt ) const 399 { 400 ASSERT( nCnt < aCompType.size(),"No CompressionType today!"); 401 return aCompType[ nCnt ]; 402 } 403 404 inline size_t SwScriptInfo::CountHiddenChg() const { return aHiddenChg.size(); }; 405 inline xub_StrLen SwScriptInfo::GetHiddenChg( const size_t nCnt ) const 406 { 407 ASSERT( nCnt < aHiddenChg.size(),"No HiddenChg today!"); 408 return aHiddenChg[ nCnt ]; 409 } 410 411 412 #endif 413