1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.  Oracle designates this
7  * particular file as subject to the "Classpath" exception as provided
8  * by Oracle in the LICENSE file that accompanied this code.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  *
24  */
25 
26 /*
27  **********************************************************************
28  *   Copyright (C) 1998-2010, International Business Machines
29  *   Corporation and others.  All Rights Reserved.
30  **********************************************************************
31  */
32 
33 #ifndef __LEGLYPHSTORAGE_H
34 #define __LEGLYPHSTORAGE_H
35 
36 #include "LETypes.h"
37 #include "LEInsertionList.h"
38 
39 /**
40  * \file
41  * \brief C++ API: This class encapsulates the per-glyph storage used by the ICU LayoutEngine.
42  */
43 
44 U_NAMESPACE_BEGIN
45 
46 /**
47  * This class encapsulates the per-glyph storage used by the ICU LayoutEngine.
48  * For each glyph it holds the glyph ID, the index of the backing store character
49  * which produced the glyph, the X and Y position of the glyph and an auxillary data
50  * pointer.
51  *
52  * The storage is growable using the <code>LEInsertionList</code> class.
53  *
54  *
55  * @see LEInsertionList.h
56  *
57  * @stable ICU 3.6
58  */
59 class U_LAYOUT_API LEGlyphStorage : public UObject, protected LEInsertionCallback
60 {
61 private:
62     /**
63      * The number of entries in the per-glyph arrays.
64      *
65      * @internal
66      */
67     le_int32   fGlyphCount;
68 
69     /**
70      * The glyph ID array.
71      *
72      * @internal
73      */
74     LEGlyphID *fGlyphs;
75 
76     /**
77      * The char indices array.
78      *
79      * @internal
80      */
81     le_int32  *fCharIndices;
82 
83     /**
84      * The glyph positions array.
85      *
86      * @internal
87      */
88     float     *fPositions;
89 
90     /**
91      * The auxillary data array.
92      *
93      * @internal
94      */
95     le_uint32 *fAuxData;
96 
97 
98     /**
99      * The insertion list, used to grow the above arrays.
100      *
101      * @internal
102      */
103     LEInsertionList *fInsertionList;
104 
105     /**
106      * The source index while growing the data arrays.
107      *
108      * @internal
109      */
110     le_int32 fSrcIndex;
111 
112     /**
113      * The destination index used while growing the data arrays.
114      *
115      * @internal
116      */
117     le_int32 fDestIndex;
118 
119 protected:
120     /**
121      * This implements <code>LEInsertionCallback</code>. The <code>LEInsertionList</code>
122      * will call this method once for each insertion.
123      *
124      * @param atPosition the position of the insertion
125      * @param count the number of glyphs being inserted
126      * @param newGlyphs the address of the new glyph IDs
127      *
128      * @return <code>true</code> if <code>LEInsertionList</code> should stop
129      *         processing the insertion list after this insertion.
130      *
131      * @see LEInsertionList.h
132      *
133      * @stable ICU 3.0
134      */
135     virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]);
136 
137 public:
138 
139     /**
140      * Allocates an empty <code>LEGlyphStorage</code> object. You must call
141      * <code>allocateGlyphArray, allocatePositions and allocateAuxData</code>
142      * to allocate the data.
143      *
144      * @stable ICU 3.0
145      */
146     LEGlyphStorage();
147 
148     /**
149      * The destructor. This will deallocate all of the arrays.
150      *
151      * @stable ICU 3.0
152      */
153     ~LEGlyphStorage();
154 
155     /**
156      * This method returns the number of glyphs in the glyph array.
157      *
158      * @return the number of glyphs in the glyph array
159      *
160      * @stable ICU 3.0
161      */
162     inline le_int32 getGlyphCount() const;
163 
164     /**
165      * This method copies the glyph array into a caller supplied array.
166      * The caller must ensure that the array is large enough to hold all
167      * the glyphs.
168      *
169      * @param glyphs - the destiniation glyph array
170      * @param success - set to an error code if the operation fails
171      *
172      * @stable ICU 3.0
173      */
174     void getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const;
175 
176     /**
177      * This method copies the glyph array into a caller supplied array,
178      * ORing in extra bits. (This functionality is needed by the JDK,
179      * which uses 32 bits pre glyph idex, with the high 16 bits encoding
180      * the composite font slot number)
181      *
182      * @param glyphs - the destination (32 bit) glyph array
183      * @param extraBits - this value will be ORed with each glyph index
184      * @param success - set to an error code if the operation fails
185      *
186      * @stable ICU 3.0
187      */
188     void getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const;
189 
190     /**
191      * This method copies the character index array into a caller supplied array.
192      * The caller must ensure that the array is large enough to hold a
193      * character index for each glyph.
194      *
195      * @param charIndices - the destiniation character index array
196      * @param success - set to an error code if the operation fails
197      *
198      * @stable ICU 3.0
199      */
200     void getCharIndices(le_int32 charIndices[], LEErrorCode &success) const;
201 
202     /**
203      * This method copies the character index array into a caller supplied array.
204      * The caller must ensure that the array is large enough to hold a
205      * character index for each glyph.
206      *
207      * @param charIndices - the destiniation character index array
208      * @param indexBase - an offset which will be added to each index
209      * @param success - set to an error code if the operation fails
210      *
211      * @stable ICU 3.0
212      */
213     void getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const;
214 
215     /**
216      * This method copies the position array into a caller supplied array.
217      * The caller must ensure that the array is large enough to hold an
218      * X and Y position for each glyph, plus an extra X and Y for the
219      * advance of the last glyph.
220      *
221      * @param positions - the destiniation position array
222      * @param success - set to an error code if the operation fails
223      *
224      * @stable ICU 3.0
225      */
226     void getGlyphPositions(float positions[], LEErrorCode &success) const;
227 
228     /**
229      * This method returns the X and Y position of the glyph at
230      * the given index.
231      *
232      * Input parameters:
233      * @param glyphIndex - the index of the glyph
234      *
235      * Output parameters:
236      * @param x - the glyph's X position
237      * @param y - the glyph's Y position
238      * @param success - set to an error code if the operation fails
239      *
240      * @stable ICU 3.0
241      */
242     void getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const;
243 
244     /**
245      * This method allocates the glyph array, the char indices array and the insertion list. You
246      * must call this method before using the object. This method also initializes the char indices
247      * array.
248      *
249      * @param initialGlyphCount the initial size of the glyph and char indices arrays.
250      * @param rightToLeft <code>true</code> if the original input text is right to left.
251      * @param success set to an error code if the storage cannot be allocated of if the initial
252      *        glyph count is not positive.
253      *
254      * @stable ICU 3.0
255      */
256     void allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success);
257 
258     /**
259      * This method allocates the storage for the glyph positions. It allocates one extra X, Y
260      * position pair for the position just after the last glyph.
261      *
262      * @param success set to an error code if the positions array cannot be allocated.
263      *
264      * @return the number of X, Y position pairs allocated.
265      *
266      * @stable ICU 3.0
267      */
268     le_int32 allocatePositions(LEErrorCode &success);
269 
270     /**
271      * This method allocates the storage for the auxillary glyph data.
272      *
273      * @param success set to an error code if the aulillary data array cannot be allocated.
274      *
275      * @return the size of the auxillary data array.
276      *
277      * @stable ICU 3.6
278      */
279     le_int32 allocateAuxData(LEErrorCode &success);
280 
281     /**
282      * Copy the entire auxillary data array.
283      *
284      * @param auxData the auxillary data array will be copied to this address
285      * @param success set to an error code if the data cannot be copied
286      *
287      * @stable ICU 3.6
288      */
289     void getAuxData(le_uint32 auxData[], LEErrorCode &success) const;
290 
291     /**
292      * Get the glyph ID for a particular glyph.
293      *
294      * @param glyphIndex the index into the glyph array
295      * @param success set to an error code if the glyph ID cannot be retrieved.
296      *
297      * @return the glyph ID
298      *
299      * @stable ICU 3.0
300      */
301     LEGlyphID getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const;
302 
303     /**
304      * Get the char index for a particular glyph.
305      *
306      * @param glyphIndex the index into the glyph array
307      * @param success set to an error code if the char index cannot be retrieved.
308      *
309      * @return the character index
310      *
311      * @stable ICU 3.0
312      */
313     le_int32  getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const;
314 
315 
316     /**
317      * Get the auxillary data for a particular glyph.
318      *
319      * @param glyphIndex the index into the glyph array
320      * @param success set to an error code if the auxillary data cannot be retrieved.
321      *
322      * @return the auxillary data
323      *
324      * @stable ICU 3.6
325      */
326     le_uint32 getAuxData(le_int32 glyphIndex, LEErrorCode &success) const;
327 
328     /**
329      * This operator allows direct access to the glyph array
330      * using the index operator.
331      *
332      * @param glyphIndex the index into the glyph array
333      *
334      * @return a reference to the given location in the glyph array
335      *
336      * @stable ICU 3.0
337      */
338     inline LEGlyphID &operator[](le_int32 glyphIndex) const;
339 
340     /**
341      * Call this method to replace a single glyph in the glyph array
342      * with multiple glyphs. This method uses the <code>LEInsertionList</code>
343      * to do the insertion. It returns the address of storage where the new
344      * glyph IDs can be stored. They will not actually be inserted into the
345      * glyph array until <code>applyInsertions</code> is called.
346      *
347      * @param atIndex the index of the glyph to be replaced
348      * @param insertCount the number of glyphs to replace it with
349      * @param success set to an error code if the auxillary data cannot be retrieved.
350      *
351      * @return the address at which to store the replacement glyphs.
352      *
353      * @see LEInsertionList.h
354      *
355      * @stable ICU 4.2
356      */
357     LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success);
358 
359     /**
360      * Call this method to replace a single glyph in the glyph array
361      * with multiple glyphs. This method uses the <code>LEInsertionList</code>
362      * to do the insertion. It returns the address of storage where the new
363      * glyph IDs can be stored. They will not actually be inserted into the
364      * glyph array until <code>applyInsertions</code> is called.
365      *
366      * Note: Don't use this version, use the other version of this function which has an error code.
367      *
368      * @param atIndex the index of the glyph to be replaced
369      * @param insertCount the number of glyphs to replace it with
370      *
371      * @return the address at which to store the replacement glyphs.
372      *
373      * @see LEInsertionList.h
374      *
375      * @stable ICU 3.0
376      */
377     LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount);
378 
379     /**
380      * This method is used to reposition glyphs during Indic v2 processing.  It moves
381      * all of the relevant glyph information ( glyph, indices, positions, and auxData ),
382      * from the source position to the target position, and also allows for a marker bit
383      * to be set in the target glyph's auxData so that it won't be reprocessed later in the
384      * cycle.
385      *
386      * @param fromPosition - position of the glyph to be moved
387      * @param toPosition - target position of the glyph
388      * @param marker marker bit
389      *
390      * @stable ICU 4.2
391      */
392     void moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker);
393 
394     /**
395      * This method causes all of the glyph insertions recorded by
396      * <code>insertGlyphs</code> to be applied to the glyph array. The
397      * new slots in the char indices and the auxillary data arrays
398      * will be filled in with the values for the glyph being replaced.
399      *
400      * @return the new size of the glyph array
401      *
402      * @see LEInsertionList.h
403      *
404      * @stable ICU 3.0
405      */
406     le_int32 applyInsertions();
407 
408     /**
409      * Set the glyph ID for a particular glyph.
410      *
411      * @param glyphIndex the index of the glyph
412      * @param glyphID the new glyph ID
413      * @param success will be set to an error code if the glyph ID cannot be set.
414      *
415      * @stable ICU 3.0
416      */
417     void setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success);
418 
419     /**
420      * Set the char index for a particular glyph.
421      *
422      * @param glyphIndex the index of the glyph
423      * @param charIndex the new char index
424      * @param success will be set to an error code if the char index cannot be set.
425      *
426      * @stable ICU 3.0
427      */
428     void setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success);
429 
430     /**
431      * Set the X, Y position for a particular glyph.
432      *
433      * @param glyphIndex the index of the glyph
434      * @param x the new X position
435      * @param y the new Y position
436      * @param success will be set to an error code if the position cannot be set.
437      *
438      * @stable ICU 3.0
439      */
440     void setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success);
441 
442     /**
443      * Adjust the X, Y position for a particular glyph.
444      *
445      * @param glyphIndex the index of the glyph
446      * @param xAdjust the adjustment to the glyph's X position
447      * @param yAdjust the adjustment to the glyph's Y position
448      * @param success will be set to an error code if the glyph's position cannot be adjusted.
449      *
450      * @stable ICU 3.0
451      */
452     void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success);
453 
454     /**
455      * Set the auxillary data for a particular glyph.
456      *
457      * @param glyphIndex the index of the glyph
458      * @param auxData the new auxillary data
459      * @param success will be set to an error code if the auxillary data cannot be set.
460      *
461      * @stable ICU 3.6
462      */
463     void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success);
464 
465     /**
466      * Delete the glyph array and replace it with the one
467      * in <code>from</code>. Set the glyph array pointer
468      * in <code>from</code> to <code>NULL</code>.
469      *
470      * @param from the <code>LEGlyphStorage</code> object from which
471      *             to get the new glyph array.
472      *
473      * @stable ICU 3.0
474      */
475     void adoptGlyphArray(LEGlyphStorage &from);
476 
477     /**
478      * Delete the char indices array and replace it with the one
479      * in <code>from</code>. Set the char indices array pointer
480      * in <code>from</code> to <code>NULL</code>.
481      *
482      * @param from the <code>LEGlyphStorage</code> object from which
483      *             to get the new char indices array.
484      *
485      * @stable ICU 3.0
486      */
487     void adoptCharIndicesArray(LEGlyphStorage &from);
488 
489     /**
490      * Delete the position array and replace it with the one
491      * in <code>from</code>. Set the position array pointer
492      * in <code>from</code> to <code>NULL</code>.
493      *
494      * @param from the <code>LEGlyphStorage</code> object from which
495      *             to get the new position array.
496      *
497      * @stable ICU 3.0
498      */
499     void adoptPositionArray(LEGlyphStorage &from);
500 
501     /**
502      * Delete the auxillary data array and replace it with the one
503      * in <code>from</code>. Set the auxillary data array pointer
504      * in <code>from</code> to <code>NULL</code>.
505      *
506      * @param from the <code>LEGlyphStorage</code> object from which
507      *             to get the new auxillary data array.
508      *
509      * @stable ICU 3.0
510      */
511     void adoptAuxDataArray(LEGlyphStorage &from);
512 
513     /**
514      * Change the glyph count of this object to be the same
515      * as the one in <code>from</code>.
516      *
517      * @param from the <code>LEGlyphStorage</code> object from which
518      *             to get the new glyph count.
519      *
520      * @stable ICU 3.0
521      */
522     void adoptGlyphCount(LEGlyphStorage &from);
523 
524     /**
525      * Change the glyph count of this object to the given value.
526      *
527      * @param newGlyphCount the new glyph count.
528      *
529      * @stable ICU 3.0
530      */
531     void adoptGlyphCount(le_int32 newGlyphCount);
532 
533     /**
534      * This method frees the glyph, character index, position  and
535      * auxillary data arrays so that the LayoutEngine can be reused
536      * to layout a different characer array. (This method is also called
537      * by the destructor)
538      *
539      * @stable ICU 3.0
540      */
541     void reset();
542 
543     /**
544      * ICU "poor man's RTTI", returns a UClassID for the actual class.
545      *
546      * @stable ICU 3.0
547      */
548     virtual UClassID getDynamicClassID() const;
549 
550     /**
551      * ICU "poor man's RTTI", returns a UClassID for this class.
552      *
553      * @stable ICU 3.0
554      */
555     static UClassID getStaticClassID();
556 };
557 
getGlyphCount()558 inline le_int32 LEGlyphStorage::getGlyphCount() const
559 {
560     return fGlyphCount;
561 }
562 
563 inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
564 {
565     return fGlyphs[glyphIndex];
566 }
567 
568 
569 U_NAMESPACE_END
570 #endif
571