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