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