1/*
2 **********************************************************************
3 *   Copyright (C) 2003-2008, International Business Machines
4 *   Corporation and others.  All Rights Reserved.
5 **********************************************************************
6 */
7
8#ifndef __RUNARRAYS_H
9
10#define __RUNARRAYS_H
11
12#include "layout/LETypes.h"
13#include "layout/LEFontInstance.h"
14
15#include "unicode/utypes.h"
16#include "unicode/locid.h"
17
18/**
19 * \file
20 * \brief C++ API: base class for building classes which represent data that is associated with runs of text.
21 */
22
23U_NAMESPACE_BEGIN
24
25/**
26 * The initial size of an array if it is unspecified.
27 *
28 * @stable ICU 3.2
29 */
30#define INITIAL_CAPACITY 16
31
32/**
33 * When an array needs to grow, it will double in size until
34 * it becomes this large, then it will grow by this amount.
35 *
36 * @stable ICU 3.2
37 */
38#define CAPACITY_GROW_LIMIT 128
39
40/**
41 * The <code>RunArray</code> class is a base class for building classes
42 * which represent data that is associated with runs of text. This class
43 * maintains an array of limit indices into the text, subclasses
44 * provide one or more arrays of data.
45 *
46 * @stable ICU 3.2
47 */
48class U_LAYOUTEX_API RunArray : public UObject
49{
50public:
51    /**
52     * Construct a <code>RunArray</code> object from a pre-existing
53     * array of limit indices.
54     *
55     * @param limits is an array of limit indices. This array must remain
56     *               valid until the <code>RunArray</code> object is destroyed.
57     *
58     * @param count is the number of entries in the limit array.
59     *
60     * @stable ICU 3.2
61     */
62    inline RunArray(const le_int32 *limits, le_int32 count);
63
64    /**
65     * Construct an empty <code>RunArray</code> object. Clients can add limit
66     * indices array using the <code>add</code> method.
67     *
68     * @param initialCapacity is the initial size of the limit indices array. If
69     *        this value is zero, no array will be allocated.
70     *
71     * @see add
72     *
73     * @stable ICU 3.2
74     */
75    RunArray(le_int32 initialCapacity);
76
77    /**
78     * The destructor; virtual so that subclass destructors are invoked as well.
79     *
80     * @stable ICU 3.2
81     */
82    virtual ~RunArray();
83
84    /**
85     * Get the number of entries in the limit indices array.
86     *
87     * @return the number of entries in the limit indices array.
88     *
89     * @stable ICU 3.2
90     */
91    inline le_int32 getCount() const;
92
93    /**
94     * Reset the limit indices array. This method sets the number of entries in the
95     * limit indices array to zero. It does not delete the array.
96     *
97     * Note: Subclass arrays will also be reset and not deleted.
98     *
99     * @stable ICU 3.6
100     */
101    inline void reset();
102
103    /**
104     * Get the last limit index. This is the number of characters in
105     * the text.
106     *
107     * @return the last limit index.
108     *
109     * @stable ICU 3.2
110     */
111    inline le_int32 getLimit() const;
112
113    /**
114     * Get the limit index for a particular run of text.
115     *
116     * @param run is the run. This is an index into the limit index array.
117     *
118     * @return the limit index for the run, or -1 if <code>run</code> is out of bounds.
119     *
120     * @stable ICU 3.2
121     */
122    inline le_int32 getLimit(le_int32 run) const;
123
124    /**
125     * Add a limit index to the limit indices array and return the run index
126     * where it was stored. If the array does not exist, it will be created by
127     * calling the <code>init</code> method. If it is full, it will be grown by
128     * calling the <code>grow</code> method.
129     *
130     * If the <code>RunArray</code> object was created with a client-supplied
131     * limit indices array, this method will return a run index of -1.
132     *
133     * Subclasses should not override this method. Rather they should provide
134     * a new <code>add</code> method which takes a limit index along with whatever
135     * other data they implement. The new <code>add</code> method should
136     * first call this method to grow the data arrays, and use the return value
137     * to store the data in their own arrays.
138     *
139     * @param limit is the limit index to add to the array.
140     *
141     * @return the run index where the limit index was stored, or -1 if the limit index cannt be stored.
142     *
143     * @see init
144     * @see grow
145     *
146     * @stable ICU 3.2
147     */
148    le_int32 add(le_int32 limit);
149
150    /**
151     * ICU "poor man's RTTI", returns a UClassID for this class.
152     *
153     * @stable ICU 3.2
154     */
155    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
156
157    /**
158     * ICU "poor man's RTTI", returns a UClassID for the actual class.
159     *
160     * @stable ICU 3.2
161     */
162    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
163
164protected:
165    /**
166     * Create a data array with the given initial size. This method will be
167     * called by the <code>add</code> method if there is no limit indices
168     * array. Subclasses which override this method must also call it from
169     * the overriding method to create the limit indices array.
170     *
171     * @param capacity is the initial size of the data array.
172     *
173     * @see add
174     *
175     * @stable ICU 3.2
176     */
177    virtual void init(le_int32 capacity);
178
179    /**
180     * Grow a data array to the given initial size. This method will be
181     * called by the <code>add</code> method if the limit indices
182     * array is full. Subclasses which override this method must also call it from
183     * the overriding method to grow the limit indices array.
184     *
185     * @param capacity is the initial size of the data array.
186     *
187     * @see add
188     *
189     * @stable ICU 3.2
190     */
191    virtual void grow(le_int32 capacity);
192
193    /**
194     * Set by the constructors to indicate whether
195     * or not the client supplied the data arrays.
196     * If they were supplied by the client, the
197     * <code>add</code> method won't change the arrays
198     * and the destructor won't delete them.
199     *
200     * @stable ICU 3.2
201     */
202    le_bool fClientArrays;
203
204private:
205    /**
206     * The address of this static class variable serves as this class's ID
207     * for ICU "poor man's RTTI".
208     */
209    static const char fgClassID;
210
211    le_int32 ensureCapacity();
212
213    inline RunArray();
214    inline RunArray(const RunArray & /*other*/);
215    inline RunArray &operator=(const RunArray & /*other*/) { return *this; };
216
217    const le_int32 *fLimits;
218          le_int32  fCount;
219          le_int32  fCapacity;
220};
221
222inline RunArray::RunArray()
223    : UObject(), fClientArrays(FALSE), fLimits(NULL), fCount(0), fCapacity(0)
224{
225    // nothing else to do...
226}
227
228inline RunArray::RunArray(const RunArray & /*other*/)
229    : UObject(), fClientArrays(FALSE), fLimits(NULL), fCount(0), fCapacity(0)
230{
231    // nothing else to do...
232}
233
234inline RunArray::RunArray(const le_int32 *limits, le_int32 count)
235    : UObject(), fClientArrays(TRUE), fLimits(limits), fCount(count), fCapacity(count)
236{
237    // nothing else to do...
238}
239
240inline le_int32 RunArray::getCount() const
241{
242    return fCount;
243}
244
245inline void RunArray::reset()
246{
247    fCount = 0;
248}
249
250inline le_int32 RunArray::getLimit(le_int32 run) const
251{
252    if (run < 0 || run >= fCount) {
253        return -1;
254    }
255
256    return fLimits[run];
257}
258
259inline le_int32 RunArray::getLimit() const
260{
261    return getLimit(fCount - 1);
262}
263
264/**
265 * The <code>FontRuns</code> class associates pointers to <code>LEFontInstance</code>
266 * objects with runs of text.
267 *
268 * @stable ICU 3.2
269 */
270class U_LAYOUTEX_API FontRuns : public RunArray
271{
272public:
273    /**
274     * Construct a <code>FontRuns</code> object from pre-existing arrays of fonts
275     * and limit indices.
276     *
277     * @param fonts is the address of an array of pointers to <code>LEFontInstance</code> objects. This
278     *              array, and the <code>LEFontInstance</code> objects to which it points must remain
279     *              valid until the <code>FontRuns</code> object is destroyed.
280     *
281     * @param limits is the address of an array of limit indices. This array must remain valid until
282     *               the <code>FontRuns</code> object is destroyed.
283     *
284     * @param count is the number of entries in the two arrays.
285     *
286     * @stable ICU 3.2
287     */
288    inline FontRuns(const LEFontInstance **fonts, const le_int32 *limits, le_int32 count);
289
290    /**
291     * Construct an empty <code>FontRuns</code> object. Clients can add font and limit
292     * indices arrays using the <code>add</code> method.
293     *
294     * @param initialCapacity is the initial size of the font and limit indices arrays. If
295     *        this value is zero, no arrays will be allocated.
296     *
297     * @see add
298     *
299     * @stable ICU 3.2
300     */
301    FontRuns(le_int32 initialCapacity);
302
303    /**
304     * The destructor; virtual so that subclass destructors are invoked as well.
305     *
306     * @stable ICU 3.2
307     */
308    virtual ~FontRuns();
309
310    /**
311     * Get the <code>LEFontInstance</code> object assoicated with the given run
312     * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
313     * limit index.
314     *
315     * @param run is the index into the font and limit indices arrays.
316     *
317     * @return the <code>LEFontInstance</code> associated with the given text run.
318     *
319     * @see RunArray::getLimit
320     *
321     * @stable ICU 3.2
322     */
323    const LEFontInstance *getFont(le_int32 run) const;
324
325
326    /**
327     * Add an <code>LEFontInstance</code> and limit index pair to the data arrays and return
328     * the run index where the data was stored. This  method calls
329     * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
330     *
331     * If the <code>FontRuns</code> object was created with a client-supplied
332     * font and limit indices arrays, this method will return a run index of -1.
333     *
334     * Subclasses should not override this method. Rather they should provide a new <code>add</code>
335     * method which takes a font and a limit index along with whatever other data they implement.
336     * The new <code>add</code> method should first call this method to grow the font and limit indices
337     * arrays, and use the returned run index to store data their own arrays.
338     *
339     * @param font is the address of the <code>LEFontInstance</code> to add. This object must
340     *             remain valid until the <code>FontRuns</code> object is destroyed.
341     *
342     * @param limit is the limit index to add
343     *
344     * @return the run index where the font and limit index were stored, or -1 if the data cannot be stored.
345     *
346     * @stable ICU 3.2
347     */
348    le_int32 add(const LEFontInstance *font, le_int32 limit);
349
350    /**
351     * ICU "poor man's RTTI", returns a UClassID for this class.
352     *
353     * @stable ICU 3.2
354     */
355    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
356
357    /**
358     * ICU "poor man's RTTI", returns a UClassID for the actual class.
359     *
360     * @stable ICU 3.2
361     */
362    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
363
364protected:
365    virtual void init(le_int32 capacity);
366    virtual void grow(le_int32 capacity);
367
368private:
369
370    inline FontRuns();
371    inline FontRuns(const FontRuns &other);
372    inline FontRuns &operator=(const FontRuns & /*other*/) { return *this; };
373
374    /**
375     * The address of this static class variable serves as this class's ID
376     * for ICU "poor man's RTTI".
377     */
378    static const char fgClassID;
379
380    const LEFontInstance **fFonts;
381};
382
383inline FontRuns::FontRuns()
384    : RunArray(0), fFonts(NULL)
385{
386    // nothing else to do...
387}
388
389inline FontRuns::FontRuns(const FontRuns & /*other*/)
390    : RunArray(0), fFonts(NULL)
391{
392    // nothing else to do...
393}
394
395inline FontRuns::FontRuns(const LEFontInstance **fonts, const le_int32 *limits, le_int32 count)
396    : RunArray(limits, count), fFonts(fonts)
397{
398    // nothing else to do...
399}
400
401/**
402 * The <code>LocaleRuns</code> class associates pointers to <code>Locale</code>
403 * objects with runs of text.
404 *
405 * @stable ICU 3.2
406 */
407class U_LAYOUTEX_API LocaleRuns : public RunArray
408{
409public:
410    /**
411     * Construct a <code>LocaleRuns</code> object from pre-existing arrays of locales
412     * and limit indices.
413     *
414     * @param locales is the address of an array of pointers to <code>Locale</code> objects. This array,
415     *                and the <code>Locale</code> objects to which it points, must remain valid until
416     *                the <code>LocaleRuns</code> object is destroyed.
417     *
418     * @param limits is the address of an array of limit indices. This array must remain valid until the
419     *               <code>LocaleRuns</code> object is destroyed.
420     *
421     * @param count is the number of entries in the two arrays.
422     *
423     * @stable ICU 3.2
424     */
425    inline LocaleRuns(const Locale **locales, const le_int32 *limits, le_int32 count);
426
427    /**
428     * Construct an empty <code>LocaleRuns</code> object. Clients can add locale and limit
429     * indices arrays using the <code>add</code> method.
430     *
431     * @param initialCapacity is the initial size of the locale and limit indices arrays. If
432     *        this value is zero, no arrays will be allocated.
433     *
434     * @see add
435     *
436     * @stable ICU 3.2
437     */
438    LocaleRuns(le_int32 initialCapacity);
439
440    /**
441     * The destructor; virtual so that subclass destructors are invoked as well.
442     *
443     * @stable ICU 3.2
444     */
445    virtual ~LocaleRuns();
446
447    /**
448     * Get the <code>Locale</code> object assoicated with the given run
449     * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
450     * limit index.
451     *
452     * @param run is the index into the font and limit indices arrays.
453     *
454     * @return the <code>Locale</code> associated with the given text run.
455     *
456     * @see RunArray::getLimit
457     *
458     * @stable ICU 3.2
459     */
460    const Locale *getLocale(le_int32 run) const;
461
462
463    /**
464     * Add a <code>Locale</code> and limit index pair to the data arrays and return
465     * the run index where the data was stored. This  method calls
466     * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
467     *
468     * If the <code>LocaleRuns</code> object was created with a client-supplied
469     * locale and limit indices arrays, this method will return a run index of -1.
470     *
471     * Subclasses should not override this method. Rather they should provide a new <code>add</code>
472     * method which takes a locale and a limit index along with whatever other data they implement.
473     * The new <code>add</code> method should first call this method to grow the font and limit indices
474     * arrays, and use the returned run index to store data their own arrays.
475     *
476     * @param locale is the address of the <code>Locale</code> to add. This object must remain valid
477     *               until the <code>LocaleRuns</code> object is destroyed.
478     *
479     * @param limit is the limit index to add
480     *
481     * @return the run index where the locale and limit index were stored, or -1 if the data cannot be stored.
482     *
483     * @stable ICU 3.2
484     */
485    le_int32 add(const Locale *locale, le_int32 limit);
486
487    /**
488     * ICU "poor man's RTTI", returns a UClassID for this class.
489     *
490     * @stable ICU 3.2
491     */
492    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
493
494    /**
495     * ICU "poor man's RTTI", returns a UClassID for the actual class.
496     *
497     * @stable ICU 3.2
498     */
499    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
500
501protected:
502    virtual void init(le_int32 capacity);
503    virtual void grow(le_int32 capacity);
504
505    /**
506     * @internal
507     */
508    const Locale **fLocales;
509
510private:
511
512    inline LocaleRuns();
513    inline LocaleRuns(const LocaleRuns &other);
514    inline LocaleRuns &operator=(const LocaleRuns & /*other*/) { return *this; };
515
516    /**
517     * The address of this static class variable serves as this class's ID
518     * for ICU "poor man's RTTI".
519     */
520    static const char fgClassID;
521};
522
523inline LocaleRuns::LocaleRuns()
524    : RunArray(0), fLocales(NULL)
525{
526    // nothing else to do...
527}
528
529inline LocaleRuns::LocaleRuns(const LocaleRuns & /*other*/)
530    : RunArray(0), fLocales(NULL)
531{
532    // nothing else to do...
533}
534
535inline LocaleRuns::LocaleRuns(const Locale **locales, const le_int32 *limits, le_int32 count)
536    : RunArray(limits, count), fLocales(locales)
537{
538    // nothing else to do...
539}
540
541/**
542 * The <code>ValueRuns</code> class associates integer values with runs of text.
543 *
544 * @stable ICU 3.2
545 */
546class U_LAYOUTEX_API ValueRuns : public RunArray
547{
548public:
549    /**
550     * Construct a <code>ValueRuns</code> object from pre-existing arrays of values
551     * and limit indices.
552     *
553     * @param values is the address of an array of integer. This array must remain valid until
554     *               the <code>ValueRuns</code> object is destroyed.
555     *
556     * @param limits is the address of an array of limit indices. This array must remain valid until
557     *               the <code>ValueRuns</code> object is destroyed.
558     *
559     * @param count is the number of entries in the two arrays.
560     *
561     * @stable ICU 3.2
562     */
563    inline ValueRuns(const le_int32 *values, const le_int32 *limits, le_int32 count);
564
565    /**
566     * Construct an empty <code>ValueRuns</code> object. Clients can add value and limit
567     * indices arrays using the <code>add</code> method.
568     *
569     * @param initialCapacity is the initial size of the value and limit indices arrays. If
570     *        this value is zero, no arrays will be allocated.
571     *
572     * @see add
573     *
574     * @stable ICU 3.2
575     */
576    ValueRuns(le_int32 initialCapacity);
577
578    /**
579     * The destructor; virtual so that subclass destructors are invoked as well.
580     *
581     * @stable ICU 3.2
582     */
583    virtual ~ValueRuns();
584
585    /**
586     * Get the integer value assoicated with the given run
587     * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
588     * limit index.
589     *
590     * @param run is the index into the font and limit indices arrays.
591     *
592     * @return the integer value associated with the given text run.
593     *
594     * @see RunArray::getLimit
595     *
596     * @stable ICU 3.2
597     */
598    le_int32 getValue(le_int32 run) const;
599
600
601    /**
602     * Add an integer value and limit index pair to the data arrays and return
603     * the run index where the data was stored. This  method calls
604     * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
605     *
606     * If the <code>ValueRuns</code> object was created with a client-supplied
607     * font and limit indices arrays, this method will return a run index of -1.
608     *
609     * Subclasses should not override this method. Rather they should provide a new <code>add</code>
610     * method which takes an integer value and a limit index along with whatever other data they implement.
611     * The new <code>add</code> method should first call this method to grow the font and limit indices
612     * arrays, and use the returned run index to store data their own arrays.
613     *
614     * @param value is the integer value to add
615     *
616     * @param limit is the limit index to add
617     *
618     * @return the run index where the value and limit index were stored, or -1 if the data cannot be stored.
619     *
620     * @stable ICU 3.2
621     */
622    le_int32 add(le_int32 value, le_int32 limit);
623
624    /**
625     * ICU "poor man's RTTI", returns a UClassID for this class.
626     *
627     * @stable ICU 3.2
628     */
629    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
630
631    /**
632     * ICU "poor man's RTTI", returns a UClassID for the actual class.
633     *
634     * @stable ICU 3.2
635     */
636    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }
637
638protected:
639    virtual void init(le_int32 capacity);
640    virtual void grow(le_int32 capacity);
641
642private:
643
644    inline ValueRuns();
645    inline ValueRuns(const ValueRuns &other);
646    inline ValueRuns &operator=(const ValueRuns & /*other*/) { return *this; };
647
648    /**
649     * The address of this static class variable serves as this class's ID
650     * for ICU "poor man's RTTI".
651     */
652    static const char fgClassID;
653
654    const le_int32 *fValues;
655};
656
657inline ValueRuns::ValueRuns()
658    : RunArray(0), fValues(NULL)
659{
660    // nothing else to do...
661}
662
663inline ValueRuns::ValueRuns(const ValueRuns & /*other*/)
664    : RunArray(0), fValues(NULL)
665{
666    // nothing else to do...
667}
668
669inline ValueRuns::ValueRuns(const le_int32 *values, const le_int32 *limits, le_int32 count)
670    : RunArray(limits, count), fValues(values)
671{
672    // nothing else to do...
673}
674
675U_NAMESPACE_END
676#endif
677