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