1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4  **********************************************************************
5  *   Copyright (C) 2003, International Business Machines
6  *   Corporation and others.  All Rights Reserved.
7  **********************************************************************
8  */
9 
10 #include "layout/LETypes.h"
11 #include "layout/LEFontInstance.h"
12 
13 #include "unicode/locid.h"
14 
15 #include "layout/RunArrays.h"
16 
17 U_NAMESPACE_BEGIN
18 
19 const char RunArray::fgClassID = 0;
20 
RunArray(le_int32 initialCapacity)21 RunArray::RunArray(le_int32 initialCapacity)
22     : fClientArrays(FALSE), fLimits(NULL), fCount(0), fCapacity(initialCapacity)
23 {
24     if (initialCapacity > 0) {
25         fLimits = LE_NEW_ARRAY(le_int32, fCapacity);
26     }
27 }
28 
~RunArray()29 RunArray::~RunArray()
30 {
31     if (! fClientArrays) {
32         LE_DELETE_ARRAY(fLimits);
33         fLimits = NULL;
34     }
35 }
36 
ensureCapacity()37 le_int32 RunArray::ensureCapacity()
38 {
39     if (fCount >= fCapacity) {
40         if (fCapacity == 0) {
41             fCapacity = INITIAL_CAPACITY;
42             init(fCapacity);
43         } else {
44             fCapacity += (fCapacity < CAPACITY_GROW_LIMIT ? fCapacity : CAPACITY_GROW_LIMIT);
45             grow(fCapacity);
46         }
47     }
48 
49     return fCount++;
50 }
51 
init(le_int32 capacity)52 void RunArray::init(le_int32 capacity)
53 {
54     fLimits = LE_NEW_ARRAY(le_int32, capacity);
55 }
56 
grow(le_int32 newCapacity)57 void RunArray::grow(le_int32 newCapacity)
58 {
59     fLimits = (le_int32 *) LE_GROW_ARRAY(fLimits, newCapacity);
60 }
61 
add(le_int32 limit)62 le_int32 RunArray::add(le_int32 limit)
63 {
64     if (fClientArrays) {
65         return -1;
66     }
67 
68     le_int32  index  = ensureCapacity();
69     le_int32 *limits = (le_int32 *) fLimits;
70 
71     limits[index] = limit;
72 
73     return index;
74 }
75 
76 const char FontRuns::fgClassID = 0;
77 
FontRuns(le_int32 initialCapacity)78 FontRuns::FontRuns(le_int32 initialCapacity)
79     : RunArray(initialCapacity), fFonts(NULL)
80 {
81     if (initialCapacity > 0) {
82         fFonts = LE_NEW_ARRAY(const LEFontInstance *, initialCapacity);
83     }
84 }
85 
~FontRuns()86 FontRuns::~FontRuns()
87 {
88     if (! fClientArrays) {
89         LE_DELETE_ARRAY(fFonts);
90         fFonts = NULL;
91     }
92 }
93 
init(le_int32 capacity)94 void FontRuns::init(le_int32 capacity)
95 {
96     RunArray::init(capacity);
97     fFonts = LE_NEW_ARRAY(const LEFontInstance *, capacity);
98 }
99 
grow(le_int32 capacity)100 void FontRuns::grow(le_int32 capacity)
101 {
102     RunArray::grow(capacity);
103     fFonts = (const LEFontInstance **) LE_GROW_ARRAY(fFonts, capacity);
104 }
105 
add(const LEFontInstance * font,le_int32 limit)106 le_int32 FontRuns::add(const LEFontInstance *font, le_int32 limit)
107 {
108     le_int32 index = RunArray::add(limit);
109 
110     if (index >= 0) {
111         LEFontInstance **fonts = (LEFontInstance **) fFonts;
112 
113         fonts[index] = (LEFontInstance *) font;
114     }
115 
116     return index;
117 }
118 
getFont(le_int32 run) const119 const LEFontInstance *FontRuns::getFont(le_int32 run) const
120 {
121     if (run < 0 || run >= getCount()) {
122         return NULL;
123     }
124 
125     return fFonts[run];
126 }
127 
128 const char LocaleRuns::fgClassID = 0;
129 
LocaleRuns(le_int32 initialCapacity)130 LocaleRuns::LocaleRuns(le_int32 initialCapacity)
131     : RunArray(initialCapacity), fLocales(NULL)
132 {
133     if (initialCapacity > 0) {
134         fLocales = LE_NEW_ARRAY(const Locale *, initialCapacity);
135     }
136 }
137 
~LocaleRuns()138 LocaleRuns::~LocaleRuns()
139 {
140     if (! fClientArrays) {
141         LE_DELETE_ARRAY(fLocales);
142         fLocales = NULL;
143     }
144 }
145 
init(le_int32 capacity)146 void LocaleRuns::init(le_int32 capacity)
147 {
148     RunArray::init(capacity);
149     fLocales = LE_NEW_ARRAY(const Locale *, capacity);
150 }
151 
grow(le_int32 capacity)152 void LocaleRuns::grow(le_int32 capacity)
153 {
154     RunArray::grow(capacity);
155     fLocales = (const Locale **) LE_GROW_ARRAY(fLocales, capacity);
156 }
157 
add(const Locale * locale,le_int32 limit)158 le_int32 LocaleRuns::add(const Locale *locale, le_int32 limit)
159 {
160     le_int32 index = RunArray::add(limit);
161 
162     if (index >= 0) {
163         Locale **locales = (Locale **) fLocales;
164 
165         locales[index] = (Locale *) locale;
166     }
167 
168     return index;
169 }
170 
getLocale(le_int32 run) const171 const Locale *LocaleRuns::getLocale(le_int32 run) const
172 {
173     if (run < 0 || run >= getCount()) {
174         return NULL;
175     }
176 
177     return fLocales[run];
178 }
179 
180 const char ValueRuns::fgClassID = 0;
181 
ValueRuns(le_int32 initialCapacity)182 ValueRuns::ValueRuns(le_int32 initialCapacity)
183     : RunArray(initialCapacity), fValues(NULL)
184 {
185     if (initialCapacity > 0) {
186         fValues = LE_NEW_ARRAY(le_int32, initialCapacity);
187     }
188 }
189 
~ValueRuns()190 ValueRuns::~ValueRuns()
191 {
192     if (! fClientArrays) {
193         LE_DELETE_ARRAY(fValues);
194         fValues = NULL;
195     }
196 }
197 
init(le_int32 capacity)198 void ValueRuns::init(le_int32 capacity)
199 {
200     RunArray::init(capacity);
201     fValues = LE_NEW_ARRAY(le_int32, capacity);
202 }
203 
grow(le_int32 capacity)204 void ValueRuns::grow(le_int32 capacity)
205 {
206     RunArray::grow(capacity);
207     fValues = (const le_int32 *) LE_GROW_ARRAY(fValues, capacity);
208 }
209 
add(le_int32 value,le_int32 limit)210 le_int32 ValueRuns::add(le_int32 value, le_int32 limit)
211 {
212     le_int32 index = RunArray::add(limit);
213 
214     if (index >= 0) {
215         le_int32 *values = (le_int32 *) fValues;
216 
217         values[index] = value;
218     }
219 
220     return index;
221 }
222 
getValue(le_int32 run) const223 le_int32 ValueRuns::getValue(le_int32 run) const
224 {
225     if (run < 0 || run >= getCount()) {
226         return -1;
227     }
228 
229     return fValues[run];
230 }
231 
232 U_NAMESPACE_END
233