You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
504 lines
12 KiB
504 lines
12 KiB
// © 2016 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
/*
|
|
*
|
|
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
|
*
|
|
*/
|
|
|
|
#include "layout/LETypes.h"
|
|
#include "layout/loengine.h"
|
|
#include "layout/plruns.h"
|
|
|
|
#include "unicode/locid.h"
|
|
|
|
#include "layout/LayoutEngine.h"
|
|
#include "layout/RunArrays.h"
|
|
|
|
U_NAMESPACE_USE
|
|
|
|
U_CAPI pl_fontRuns * U_EXPORT2
|
|
pl_openFontRuns(const le_font **fonts,
|
|
const le_int32 *limits,
|
|
le_int32 count)
|
|
{
|
|
return (pl_fontRuns *) new FontRuns((const LEFontInstance **) fonts, limits, count);
|
|
}
|
|
|
|
U_CAPI pl_fontRuns * U_EXPORT2
|
|
pl_openEmptyFontRuns(le_int32 initialCapacity)
|
|
{
|
|
return (pl_fontRuns *) new FontRuns(initialCapacity);
|
|
}
|
|
|
|
U_CAPI void U_EXPORT2
|
|
pl_closeFontRuns(pl_fontRuns *fontRuns)
|
|
{
|
|
FontRuns *fr = (FontRuns *) fontRuns;
|
|
|
|
delete fr;
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getFontRunCount(const pl_fontRuns *fontRuns)
|
|
{
|
|
const FontRuns *fr = (const FontRuns *) fontRuns;
|
|
|
|
if (fr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return fr->getCount();
|
|
}
|
|
|
|
U_CAPI void U_EXPORT2
|
|
pl_resetFontRuns(pl_fontRuns *fontRuns)
|
|
{
|
|
FontRuns *fr = (FontRuns *) fontRuns;
|
|
|
|
if (fr != NULL) {
|
|
fr->reset();
|
|
}
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getFontRunLastLimit(const pl_fontRuns *fontRuns)
|
|
{
|
|
const FontRuns *fr = (const FontRuns *) fontRuns;
|
|
|
|
if (fr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return fr->getLimit();
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getFontRunLimit(const pl_fontRuns *fontRuns,
|
|
le_int32 run)
|
|
{
|
|
const FontRuns *fr = (const FontRuns *) fontRuns;
|
|
|
|
if (fr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return fr->getLimit(run);
|
|
}
|
|
|
|
U_CAPI const le_font * U_EXPORT2
|
|
pl_getFontRunFont(const pl_fontRuns *fontRuns,
|
|
le_int32 run)
|
|
{
|
|
const FontRuns *fr = (const FontRuns *) fontRuns;
|
|
|
|
if (fr == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
return (const le_font *) fr->getFont(run);
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_addFontRun(pl_fontRuns *fontRuns,
|
|
const le_font *font,
|
|
le_int32 limit)
|
|
{
|
|
FontRuns *fr = (FontRuns *) fontRuns;
|
|
|
|
if (fr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return fr->add((const LEFontInstance *) font, limit);
|
|
}
|
|
|
|
U_CAPI pl_valueRuns * U_EXPORT2
|
|
pl_openValueRuns(const le_int32 *values,
|
|
const le_int32 *limits,
|
|
le_int32 count)
|
|
{
|
|
return (pl_valueRuns *) new ValueRuns(values, limits, count);
|
|
}
|
|
|
|
U_CAPI pl_valueRuns * U_EXPORT2
|
|
pl_openEmptyValueRuns(le_int32 initialCapacity)
|
|
{
|
|
return (pl_valueRuns *) new ValueRuns(initialCapacity);
|
|
}
|
|
|
|
U_CAPI void U_EXPORT2
|
|
pl_closeValueRuns(pl_valueRuns *valueRuns)
|
|
{
|
|
ValueRuns *vr = (ValueRuns *) valueRuns;
|
|
|
|
delete vr;
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getValueRunCount(const pl_valueRuns *valueRuns)
|
|
{
|
|
const ValueRuns *vr = (const ValueRuns *) valueRuns;
|
|
|
|
if (vr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return vr->getCount();
|
|
}
|
|
|
|
U_CAPI void U_EXPORT2
|
|
pl_resetValueRuns(pl_valueRuns *valueRuns)
|
|
{
|
|
ValueRuns *vr = (ValueRuns *) valueRuns;
|
|
|
|
if (vr != NULL) {
|
|
vr->reset();
|
|
}
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getValueRunLastLimit(const pl_valueRuns *valueRuns)
|
|
{
|
|
const ValueRuns *vr = (const ValueRuns *) valueRuns;
|
|
|
|
if (vr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return vr->getLimit();
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getValueRunLimit(const pl_valueRuns *valueRuns,
|
|
le_int32 run)
|
|
{
|
|
const ValueRuns *vr = (const ValueRuns *) valueRuns;
|
|
|
|
if (vr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return vr->getLimit(run);
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getValueRunValue(const pl_valueRuns *valueRuns,
|
|
le_int32 run)
|
|
{
|
|
const ValueRuns *vr = (const ValueRuns *) valueRuns;
|
|
|
|
if (vr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return vr->getValue(run);
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_addValueRun(pl_valueRuns *valueRuns,
|
|
le_int32 value,
|
|
le_int32 limit)
|
|
{
|
|
ValueRuns *vr = (ValueRuns *) valueRuns;
|
|
|
|
if (vr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return vr->add(value, limit);
|
|
}
|
|
|
|
U_NAMESPACE_BEGIN
|
|
class ULocRuns : public LocaleRuns
|
|
{
|
|
public:
|
|
/**
|
|
* Construct a <code>LocaleRuns</code> object from pre-existing arrays of locales
|
|
* and limit indices.
|
|
*
|
|
* @param locales is the address of an array of locale name strings. This array,
|
|
* and the <code>Locale</code> objects to which it points, must remain valid until
|
|
* the <code>LocaleRuns</code> object is destroyed.
|
|
*
|
|
* @param limits is the address of an array of limit indices. This array must remain valid until the
|
|
* <code>LocaleRuns</code> object is destroyed.
|
|
*
|
|
* @param count is the number of entries in the two arrays.
|
|
*
|
|
* @draft ICU 3.8
|
|
*/
|
|
ULocRuns(const char **locales, const le_int32 *limits, le_int32 count);
|
|
|
|
/**
|
|
* Construct an empty <code>LoIDRuns</code> object. Clients can add locale and limit
|
|
* indices arrays using the <code>add</code> method.
|
|
*
|
|
* @param initialCapacity is the initial size of the locale and limit indices arrays. If
|
|
* this value is zero, no arrays will be allocated.
|
|
*
|
|
* @see add
|
|
*
|
|
* @draft ICU 3.8
|
|
*/
|
|
ULocRuns(le_int32 initialCapacity);
|
|
|
|
/**
|
|
* The destructor; virtual so that subclass destructors are invoked as well.
|
|
*
|
|
* @draft ICU 3.8
|
|
*/
|
|
virtual ~ULocRuns();
|
|
|
|
/**
|
|
* Get the name of the locale assoicated with the given run
|
|
* of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
|
|
* limit index.
|
|
*
|
|
* @param run is the index into the font and limit indices arrays.
|
|
*
|
|
* @return the locale name associated with the given text run.
|
|
*
|
|
* @see RunArray::getLimit
|
|
*
|
|
* @draft ICU 3.8
|
|
*/
|
|
const char *getLocaleName(le_int32 run) const;
|
|
|
|
/**
|
|
* Add a <code>Locale</code> and limit index pair to the data arrays and return
|
|
* the run index where the data was stored. This method calls
|
|
* <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
|
|
*
|
|
* If the <code>ULocRuns</code> object was created with a client-supplied
|
|
* locale and limit indices arrays, this method will return a run index of -1.
|
|
*
|
|
* Subclasses should not override this method. Rather they should provide a new <code>add</code>
|
|
* method which takes a locale name and a limit index along with whatever other data they implement.
|
|
* The new <code>add</code> method should first call this method to grow the font and limit indices
|
|
* arrays, and use the returned run index to store data their own arrays.
|
|
*
|
|
* @param locale is the name of the locale to add. This object must remain valid
|
|
* until the <code>ULocRuns</code> object is destroyed.
|
|
*
|
|
* @param limit is the limit index to add
|
|
*
|
|
* @return the run index where the locale and limit index were stored, or -1 if the data cannot be stored.
|
|
*
|
|
* @draft ICU 3.8
|
|
*/
|
|
le_int32 add(const char *locale, le_int32 limit);
|
|
|
|
/**
|
|
* ICU "poor man's RTTI", returns a UClassID for this class.
|
|
*
|
|
* @draft ICU 3.8
|
|
*/
|
|
static inline UClassID getStaticClassID();
|
|
|
|
/**
|
|
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
|
*
|
|
* @draft ICU 3.8
|
|
*/
|
|
virtual inline UClassID getDynamicClassID() const;
|
|
|
|
protected:
|
|
virtual void init(le_int32 capacity);
|
|
virtual void grow(le_int32 capacity);
|
|
|
|
private:
|
|
|
|
inline ULocRuns();
|
|
inline ULocRuns(const ULocRuns &other);
|
|
inline ULocRuns &operator=(const ULocRuns & /*other*/) { return *this; };
|
|
const char **fLocaleNames;
|
|
};
|
|
|
|
inline ULocRuns::ULocRuns()
|
|
: LocaleRuns(0), fLocaleNames(NULL)
|
|
{
|
|
// nothing else to do...
|
|
}
|
|
|
|
inline ULocRuns::ULocRuns(const ULocRuns & /*other*/)
|
|
: LocaleRuns(0), fLocaleNames(NULL)
|
|
{
|
|
// nothing else to do...
|
|
}
|
|
|
|
static const Locale **getLocales(const char **localeNames, le_int32 count)
|
|
{
|
|
Locale **locales = LE_NEW_ARRAY(Locale *, count);
|
|
|
|
for (int i = 0; i < count; i += 1) {
|
|
locales[i] = new Locale(Locale::createFromName(localeNames[i]));
|
|
}
|
|
|
|
return (const Locale **) locales;
|
|
}
|
|
|
|
ULocRuns::ULocRuns(const char **locales, const le_int32 *limits, le_int32 count)
|
|
: LocaleRuns(getLocales(locales, count), limits, count), fLocaleNames(locales)
|
|
{
|
|
// nothing else to do...
|
|
}
|
|
|
|
ULocRuns::ULocRuns(le_int32 initialCapacity)
|
|
: LocaleRuns(initialCapacity), fLocaleNames(NULL)
|
|
{
|
|
if(initialCapacity > 0) {
|
|
fLocaleNames = LE_NEW_ARRAY(const char *, initialCapacity);
|
|
}
|
|
}
|
|
|
|
ULocRuns::~ULocRuns()
|
|
{
|
|
le_int32 count = getCount();
|
|
|
|
for(int i = 0; i < count; i += 1) {
|
|
delete fLocales[i];
|
|
}
|
|
|
|
if (fClientArrays) {
|
|
LE_DELETE_ARRAY(fLocales);
|
|
fLocales = NULL;
|
|
} else {
|
|
LE_DELETE_ARRAY(fLocaleNames);
|
|
fLocaleNames = NULL;
|
|
}
|
|
}
|
|
|
|
void ULocRuns::init(le_int32 capacity)
|
|
{
|
|
LocaleRuns::init(capacity);
|
|
fLocaleNames = LE_NEW_ARRAY(const char *, capacity);
|
|
}
|
|
|
|
void ULocRuns::grow(le_int32 capacity)
|
|
{
|
|
LocaleRuns::grow(capacity);
|
|
fLocaleNames = (const char **) LE_GROW_ARRAY(fLocaleNames, capacity);
|
|
}
|
|
|
|
le_int32 ULocRuns::add(const char *locale, le_int32 limit)
|
|
{
|
|
Locale *loc = new Locale(Locale::createFromName(locale));
|
|
le_int32 index = LocaleRuns::add(loc, limit);
|
|
|
|
if (index >= 0) {
|
|
char **localeNames = (char **) fLocaleNames;
|
|
|
|
localeNames[index] = (char *) locale;
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
const char *ULocRuns::getLocaleName(le_int32 run) const
|
|
{
|
|
if (run < 0 || run >= getCount()) {
|
|
return NULL;
|
|
}
|
|
|
|
return fLocaleNames[run];
|
|
}
|
|
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ULocRuns)
|
|
U_NAMESPACE_END
|
|
|
|
U_CAPI pl_localeRuns * U_EXPORT2
|
|
pl_openLocaleRuns(const char **locales,
|
|
const le_int32 *limits,
|
|
le_int32 count)
|
|
{
|
|
return (pl_localeRuns *) new ULocRuns(locales, limits, count);
|
|
}
|
|
|
|
U_CAPI pl_localeRuns * U_EXPORT2
|
|
pl_openEmptyLocaleRuns(le_int32 initialCapacity)
|
|
{
|
|
return (pl_localeRuns *) new ULocRuns(initialCapacity);
|
|
}
|
|
|
|
U_CAPI void U_EXPORT2
|
|
pl_closeLocaleRuns(pl_localeRuns *localeRuns)
|
|
{
|
|
ULocRuns *lr = (ULocRuns *) localeRuns;
|
|
|
|
delete lr;
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getLocaleRunCount(const pl_localeRuns *localeRuns)
|
|
{
|
|
const ULocRuns *lr = (const ULocRuns *) localeRuns;
|
|
|
|
if (lr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return lr->getCount();
|
|
}
|
|
|
|
U_CAPI void U_EXPORT2
|
|
pl_resetLocaleRuns(pl_localeRuns *localeRuns)
|
|
{
|
|
ULocRuns *lr = (ULocRuns *) localeRuns;
|
|
|
|
if (lr != NULL) {
|
|
lr->reset();
|
|
}
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getLocaleRunLastLimit(const pl_localeRuns *localeRuns)
|
|
{
|
|
const ULocRuns *lr = (const ULocRuns *) localeRuns;
|
|
|
|
if (lr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return lr->getLimit();
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_getLocaleRunLimit(const pl_localeRuns *localeRuns,
|
|
le_int32 run)
|
|
{
|
|
const ULocRuns *lr = (const ULocRuns *) localeRuns;
|
|
|
|
if (lr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return lr->getLimit(run);
|
|
}
|
|
|
|
U_CAPI const char * U_EXPORT2
|
|
pl_getLocaleRunLocale(const pl_localeRuns *localeRuns,
|
|
le_int32 run)
|
|
{
|
|
const ULocRuns *lr = (const ULocRuns *) localeRuns;
|
|
|
|
if (lr == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
return lr->getLocaleName(run);
|
|
}
|
|
|
|
U_CAPI le_int32 U_EXPORT2
|
|
pl_addLocaleRun(pl_localeRuns *localeRuns,
|
|
const char *locale,
|
|
le_int32 limit)
|
|
{
|
|
ULocRuns *lr = (ULocRuns *) localeRuns;
|
|
|
|
if (lr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return lr->add(locale, limit);
|
|
}
|