1// Copyright (C) 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
17U_NAMESPACE_BEGIN
18
19const char RunArray::fgClassID = 0;
20
21RunArray::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
29RunArray::~RunArray()
30{
31    if (! fClientArrays) {
32        LE_DELETE_ARRAY(fLimits);
33        fLimits = NULL;
34    }
35}
36
37le_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
52void RunArray::init(le_int32 capacity)
53{
54    fLimits = LE_NEW_ARRAY(le_int32, capacity);
55}
56
57void RunArray::grow(le_int32 newCapacity)
58{
59    fLimits = (le_int32 *) LE_GROW_ARRAY(fLimits, newCapacity);
60}
61
62le_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
76const char FontRuns::fgClassID = 0;
77
78FontRuns::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
86FontRuns::~FontRuns()
87{
88    if (! fClientArrays) {
89        LE_DELETE_ARRAY(fFonts);
90        fFonts = NULL;
91    }
92}
93
94void FontRuns::init(le_int32 capacity)
95{
96    RunArray::init(capacity);
97    fFonts = LE_NEW_ARRAY(const LEFontInstance *, capacity);
98}
99
100void FontRuns::grow(le_int32 capacity)
101{
102    RunArray::grow(capacity);
103    fFonts = (const LEFontInstance **) LE_GROW_ARRAY(fFonts, capacity);
104}
105
106le_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
119const 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
128const char LocaleRuns::fgClassID = 0;
129
130LocaleRuns::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
138LocaleRuns::~LocaleRuns()
139{
140    if (! fClientArrays) {
141        LE_DELETE_ARRAY(fLocales);
142        fLocales = NULL;
143    }
144}
145
146void LocaleRuns::init(le_int32 capacity)
147{
148    RunArray::init(capacity);
149    fLocales = LE_NEW_ARRAY(const Locale *, capacity);
150}
151
152void LocaleRuns::grow(le_int32 capacity)
153{
154    RunArray::grow(capacity);
155    fLocales = (const Locale **) LE_GROW_ARRAY(fLocales, capacity);
156}
157
158le_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
171const 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
180const char ValueRuns::fgClassID = 0;
181
182ValueRuns::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
190ValueRuns::~ValueRuns()
191{
192    if (! fClientArrays) {
193        LE_DELETE_ARRAY(fValues);
194        fValues = NULL;
195    }
196}
197
198void ValueRuns::init(le_int32 capacity)
199{
200    RunArray::init(capacity);
201    fValues = LE_NEW_ARRAY(le_int32, capacity);
202}
203
204void ValueRuns::grow(le_int32 capacity)
205{
206    RunArray::grow(capacity);
207    fValues = (const le_int32 *) LE_GROW_ARRAY(fValues, capacity);
208}
209
210le_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
223le_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
232U_NAMESPACE_END
233