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
GetWord() const79 const XubString& GetWord() const { return aWord; }
80
GetBegin() const81 xub_StrLen GetBegin() const { return nBegin; }
GetEnd() const82 xub_StrLen GetEnd() const { return nBegin + nLen; }
GetLen() const83 xub_StrLen GetLen() const { return nLen; }
84
GetCurrentLanguage() const85 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 );
GetInvalidity() const132 inline xub_StrLen GetInvalidity() const { return nInvalidityPos; };
133
134 // get default direction for paragraph
GetDefaultDir() const135 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 */
ClearKashidaInvalid(xub_StrLen nStt,xub_StrLen nLen)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 */
MarkKashidasInvalid(xub_StrLen nCnt,xub_StrLen nStt,xub_StrLen nLen)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
SetInvalidity(const xub_StrLen nPos)350 inline void SwScriptInfo::SetInvalidity( const xub_StrLen nPos )
351 {
352 if ( nPos < nInvalidityPos )
353 nInvalidityPos = nPos;
354 };
CountScriptChg() const355 inline size_t SwScriptInfo::CountScriptChg() const { return aScriptChg.size(); }
GetScriptChg(const size_t nCnt) const356 inline xub_StrLen SwScriptInfo::GetScriptChg( const size_t nCnt ) const
357 {
358 ASSERT( nCnt < aScriptChg.size(),"No ScriptChange today!");
359 return aScriptChg[ nCnt ];
360 }
GetScriptType(const xub_StrLen nCnt) const361 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
CountDirChg() const367 inline size_t SwScriptInfo::CountDirChg() const { return aDirChg.size(); }
GetDirChg(const size_t nCnt) const368 inline xub_StrLen SwScriptInfo::GetDirChg( const size_t nCnt ) const
369 {
370 ASSERT( nCnt < aDirChg.size(),"No DirChange today!");
371 return aDirChg[ nCnt ];
372 }
GetDirType(const size_t nCnt) const373 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
CountKashida() const379 inline size_t SwScriptInfo::CountKashida() const { return aKashida.size(); }
GetKashida(const size_t nCnt) const380 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
CountCompChg() const386 inline size_t SwScriptInfo::CountCompChg() const { return aCompChg.size(); };
GetCompStart(const size_t nCnt) const387 inline xub_StrLen SwScriptInfo::GetCompStart( const size_t nCnt ) const
388 {
389 ASSERT( nCnt < aCompChg.size(),"No CompressionStart today!");
390 return aCompChg[ nCnt ];
391 }
GetCompLen(const size_t nCnt) const392 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
GetCompType(const size_t nCnt) const398 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
CountHiddenChg() const404 inline size_t SwScriptInfo::CountHiddenChg() const { return aHiddenChg.size(); };
GetHiddenChg(const size_t nCnt) const405 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