xref: /aoo42x/main/sw/source/core/inc/scriptinfo.hxx (revision cdf0e10c)
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