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