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
44U_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 */
59class U_LAYOUT_API LEGlyphStorage : public UObject, protected LEInsertionCallback
60{
61private:
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
119protected:
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
137public:
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
558inline le_int32 LEGlyphStorage::getGlyphCount() const
559{
560    return fGlyphCount;
561}
562
563inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
564{
565    return fGlyphs[glyphIndex];
566}
567
568
569U_NAMESPACE_END
570#endif
571