ICU-2253 Add LocaleRuns, preliminary code to map Locale to LanguageCode.

X-SVN-Rev: 11635
This commit is contained in:
Eric Mader 2003-04-23 16:16:22 +00:00
parent d84ed8d5fa
commit 841771c66d
7 changed files with 401 additions and 69 deletions

View file

@ -16,13 +16,17 @@
#include "Utilities.h"
#include "usc_impl.h" /* this is currently private! */
#include "cstring.h" /* this too! */
#include "ParagraphLayout.h"
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
struct ParagraphLayout::StyleRunInfo
{
LayoutEngine *engine;
const LEFontInstance *font;
const Locale *locale;
LEGlyphID *glyphs;
float *positions;
UScriptCode script;
@ -135,7 +139,7 @@ le_int32 StyleRuns::getRuns(le_int32 runLimits[], le_int32 styleIndices[])
* process, rather for all scripts which require
* complex processing for correct rendering.
*/
le_bool ParagraphLayout::fComplexTable[] = {
static const le_bool complexTable[] = {
false , /* Zyyy */
false, /* Qaai */
true, /* Arab */
@ -214,13 +218,14 @@ le_bool ParagraphLayout::fComplexTable[] = {
*
*/
ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
const FontRuns *fontRuns,
const ValueRuns *levelRuns,
const ValueRuns *scriptRuns,
const FontRuns *fontRuns,
const ValueRuns *levelRuns,
const ValueRuns *scriptRuns,
const LocaleRuns *localeRuns,
UBiDiLevel paragraphLevel, le_bool vertical)
: fChars(chars), fCharCount(count),
fFontRuns(NULL), fLevelRuns(levelRuns), fScriptRuns(scriptRuns),
fVertical(vertical), fClientLevels(true), fClientScripts(true), fEmbeddingLevels(NULL),
fFontRuns(NULL), fLevelRuns(levelRuns), fScriptRuns(scriptRuns), fLocaleRuns(localeRuns),
fVertical(vertical), fClientLevels(true), fClientScripts(true), fClientLocales(true), fEmbeddingLevels(NULL),
fAscent(0), fDescent(0), fLeading(0),
fGlyphToCharMap(NULL), fCharToGlyphMap(NULL), fGlyphWidths(NULL), fGlyphCount(0),
fParaBidi(NULL), fLineBidi(NULL),
@ -237,10 +242,14 @@ ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
computeScripts();
}
if (localeRuns == NULL) {
computeLocales();
}
computeSubFonts(fontRuns);
// now intersect the font, direction and script runs...
const RunArray *styleRunArrays[] = {fFontRuns, fLevelRuns, fScriptRuns};
const RunArray *styleRunArrays[] = {fFontRuns, fLevelRuns, fScriptRuns, fLocaleRuns};
le_int32 styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0];
StyleRuns styleRuns(styleRunArrays, styleCount);
LEErrorCode layoutStatus = LE_NO_ERROR;
@ -264,11 +273,12 @@ ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
fStyleRunInfo[run].runBase = runStart;
fStyleRunInfo[run].runLimit = fStyleRunLimits[run];
fStyleRunInfo[run].script = (UScriptCode) fScriptRuns->getValue(styleIndices[2]);
fStyleRunInfo[run].locale = fLocaleRuns->getLocale(styleIndices[3]);
fStyleRunInfo[run].level = (UBiDiLevel) fLevelRuns->getValue(styleIndices[1]);
fStyleRunInfo[run].glyphBase = fGlyphCount;
fStyleRunInfo[run].engine = LayoutEngine::layoutEngineFactory(fStyleRunInfo[run].font,
fStyleRunInfo[run].script, nullLanguageCode, layoutStatus);
fStyleRunInfo[run].script, getLanguageCode(fStyleRunInfo[run].locale), layoutStatus);
fStyleRunInfo[run].glyphCount = fStyleRunInfo[run].engine->layoutChars(fChars, runStart, fStyleRunLimits[run] - runStart, fCharCount,
fStyleRunInfo[run].level & 1, 0, 0, layoutStatus);
@ -351,6 +361,13 @@ ParagraphLayout::~ParagraphLayout()
fClientScripts = true;
}
if (! fClientLocales) {
delete fLocaleRuns;
fLocaleRuns = NULL;
fClientLocales = true;
}
if (fEmbeddingLevels != NULL) {
LE_DELETE_ARRAY(fEmbeddingLevels);
fEmbeddingLevels = NULL;
@ -553,6 +570,17 @@ void ParagraphLayout::computeScripts()
fScriptRuns = scriptRuns;
}
void ParagraphLayout::computeLocales()
{
LocaleRuns *localeRuns = new LocaleRuns(0);
const Locale *defaultLocale = &Locale::getDefault();
localeRuns->add(defaultLocale, fCharCount);
fLocaleRuns = localeRuns;
fClientLocales = false;
}
void ParagraphLayout::computeSubFonts(const FontRuns *fontRuns)
{
const RunArray *styleRunArrays[] = {fontRuns, fScriptRuns};
@ -592,12 +620,14 @@ void ParagraphLayout::computeSubFonts(const FontRuns *fontRuns)
void ParagraphLayout::computeMetrics()
{
le_int32 i, count = fFontRuns->getCount();
le_int32 maxDL = 0;
for (i = 0; i < count; i += 1) {
const LEFontInstance *font = fFontRuns->getFont(i);
le_int32 ascent = font->getAscent();
le_int32 descent = font->getDescent();
le_int32 leading = font->getLeading();
le_int32 dl = descent + leading;
if (ascent > fAscent) {
fAscent = ascent;
@ -610,16 +640,96 @@ void ParagraphLayout::computeMetrics()
if (leading > fLeading) {
fLeading = leading;
}
if (dl > maxDL) {
maxDL = dl;
}
}
fLeading = maxDL - fDescent;
}
#if 1
struct LanguageMap
{
const char *localeCode;
le_int32 languageCode;
};
static const LanguageMap languageMap[] =
{
{"ara", araLanguageCode}, // Arabic
{"asm", asmLanguageCode}, // Assamese
{"ben", benLanguageCode}, // Bengali
{"fas", farLanguageCode}, // Farsi
{"guj", gujLanguageCode}, // Gujarati
{"heb", iwrLanguageCode}, // Hebrew
{"hin", hinLanguageCode}, // Hindi
{"jpn", janLanguageCode}, // Japanese
{"kan", kanLanguageCode}, // Kannada
{"kas", kshLanguageCode}, // Kashmiri
{"kok", kokLanguageCode}, // Konkani
{"kor", korLanguageCode}, // Korean
// {"mal_XXX", malLanguageCode}, // Malayalam - Traditional
{"mal", mlrLanguageCode}, // Malayalam - Reformed
{"mar", marLanguageCode}, // Marathi
{"mni", mniLanguageCode}, // Manipuri
{"ori", oriLanguageCode}, // Oriya
{"san", sanLanguageCode}, // Sanskrit
{"snd", sndLanguageCode}, // Sindhi
{"sin", snhLanguageCode}, // Sinhalese
{"syr", syrLanguageCode}, // Syriac
{"tam", tamLanguageCode}, // Tamil
{"tel", telLanguageCode}, // Telugu
{"tha", thaLanguageCode}, // Thai
{"urd", urdLanguageCode}, // Urdu
{"yid", jiiLanguageCode}, // Yiddish
// {"zhp", zhpLanguageCode}, // Chinese - Phonetic
{"zho", zhsLanguageCode}, // Chinese
{"zho_CHN", zhsLanguageCode}, // Chinese - China
{"zho_HKG", zhsLanguageCode}, // Chinese - Hong Kong
{"zho_MAC", zhtLanguageCode}, // Chinese - Macao
{"zho_SGP", zhsLanguageCode}, // Chinese - Singapore
{"zho_TWN", zhtLanguageCode} // Chinese - Taiwan
};
le_int32 ParagraphLayout::getLanguageCode(const Locale *locale)
{
char code[8] = {0, 0, 0, 0, 0, 0, 0, 0};
const char *language = locale->getISO3Language();
const char *country = locale->getISO3Country();
uprv_strcat(code, language);
if ((uprv_strcmp(language, "zho") == 0) && country != NULL) {
uprv_strcat(code, "_");
uprv_strcat(code, country);
}
for (le_int32 i = 0; i < ARRAY_SIZE(languageMap); i += 1) {
if (uprv_strcmp(code, languageMap[i].localeCode) == 0) {
return languageMap[i].languageCode;
}
}
return nullLanguageCode;
}
#elif
// TODO - dummy implementation for right now...
le_int32 ParagraphLayout::getLanguageCode(const Locale *locale)
{
return nullLanguageCode;
}
#endif
le_bool ParagraphLayout::isComplex(UScriptCode script)
{
if (script < 0 || script >= USCRIPT_CODE_LIMIT) {
return false;
}
return fComplexTable[script];
return complexTable[script];
}
le_int32 ParagraphLayout::previousBreak(le_int32 charIndex)
@ -860,10 +970,13 @@ void ParagraphLayout::Line::append(const LEFontInstance *font, UBiDiDirection di
void ParagraphLayout::Line::computeMetrics()
{
le_int32 maxDL = 0;
for (le_int32 i = 0; i < fRunCount; i += 1) {
le_int32 ascent = fRuns[i]->getAscent();
le_int32 descent = fRuns[i]->getDescent();
le_int32 leading = fRuns[i]->getLeading();
le_int32 dl = descent + leading;
if (ascent > fAscent) {
fAscent = ascent;
@ -876,5 +989,11 @@ void ParagraphLayout::Line::computeMetrics()
if (leading > fLeading) {
fLeading = leading;
}
if (dl > maxDL) {
maxDL = dl;
}
}
fLeading = maxDL - fDescent;
}

View file

@ -23,22 +23,11 @@
*
* The <code>ParagraphLayout</code> object will analyze the text into runs of text in the
* same font, script and direction, and will create a <code>LayoutEngine</code> object for each run.
* The <code>LayoutEngine</code> will transform the characers into glyph codes in visual order.
* The <code>LayoutEngine</code> will transform the characters into glyph codes in visual order.
*
* Clients can use this to break a paragraph into lines, and to display the glyphs in each line.
*
*/
/*
* NOTES:
* * The documentation needs a *lot* of work...
*
* * Add some constructors which don't take all the arguments, so that clients don't have
* to fuss with the full-blown one if they're not doing anything tricky.
*
* * Might want language (or maybe locale?) runs in the constructor so that language tags
* can be passed to the LayoutEngines.
*/
class ParagraphLayout
{
public:
@ -79,6 +68,10 @@ public:
* If this pointer in <code>NULL</code> the script runs will be determined using the
* Unicode code points.
*
* @param localeRuns is a pointer to a <code>LocaleRuns</code> object representing locale runs.
* The <code>Locale</code> objects are used to determind the language of the text. If this
* pointer is <code>NULL</code> the default locale will be used for all of the text.
*
* @param paragraphLevel is the directionality of the paragraph, as in the UBiDi object.
*
* @param vertical is <code>true</code> if the paragraph should be set vertically.
@ -94,6 +87,7 @@ public:
const FontRuns *fontRuns,
const ValueRuns *levelRuns,
const ValueRuns *scriptRuns,
const LocaleRuns *localeRuns,
UBiDiLevel paragraphLevel, le_bool vertical);
~ParagraphLayout();
@ -188,7 +182,7 @@ public:
* be varied to support arbitrary paragraph shapes.
*
* @param width is the width of the line. If <code>width</code> is less than or equal
* to zero, a <code>ParagraphLayout::Line</code> object represnting the
* to zero, a <code>ParagraphLayout::Line</code> object representing the
* rest of the paragraph will be returned.
*
* @return a <code>ParagraphLayout::Line</code> object which represents the line. The caller
@ -214,10 +208,14 @@ private:
void computeScripts();
void computeLocales();
void computeSubFonts(const FontRuns *fontRuns);
void computeMetrics();
le_int32 getLanguageCode(const Locale *locale);
le_int32 getCharRun(le_int32 charIndex);
static le_bool isComplex(UScriptCode script);
@ -228,13 +226,15 @@ private:
const LEUnicode *fChars;
le_int32 fCharCount;
const FontRuns *fFontRuns;
const ValueRuns *fLevelRuns;
const ValueRuns *fScriptRuns;
const FontRuns *fFontRuns;
const ValueRuns *fLevelRuns;
const ValueRuns *fScriptRuns;
const LocaleRuns *fLocaleRuns;
le_bool fVertical;
le_bool fClientLevels;
le_bool fClientScripts;
le_bool fClientLocales;
UBiDiLevel *fEmbeddingLevels;
@ -263,8 +263,6 @@ private:
le_int32 fLastVisualRun;
float fVisualRunLastX;
float fVisualRunLastY;
static le_bool fComplexTable[];
};
inline UBiDiLevel ParagraphLayout::getParagraphLevel()
@ -396,7 +394,7 @@ inline le_int32 ParagraphLayout::Line::countRuns() const
* a paragraph. A visual run is text which is in the same font,
* script, and direction. The text is represented by an array of
* <code>LEGlyphIDs</code>, an array of (x, y) glyph positions and
* a table which maps indicies into the glyph array to indicies into
* a table which maps indices into the glyph array to indices into
* the original character array which was used to create the paragraph.
*
* These objects are only created by <code>ParagraphLayout::Line<code> objects,
@ -471,7 +469,7 @@ public:
/**
* Get the glyph-to-character map for this visual run. This maps the indices into
* the glyph array to indicies into the character array used to create the paragraph.
* the glyph array to indices into the character array used to create the paragraph.
*
* @return the address of the character-to-glyph map for this visual run. The storage
* is owned by the <code>VisualRun</code> object and must not be deleted.

View file

@ -30,8 +30,8 @@ struct TableCacheEntry
};
RenderingFontInstance::RenderingFontInstance(RenderingSurface *surface, le_int16 pointSize)
: fSurface(surface), fPointSize(pointSize), fUnitsPerEM(0), fAscent(0), fDescent(), fLeading(0),
fDeviceScaleX(1), fDeviceScaleY(1), fTableCache(NULL), fTableCacheCurr(0), fTableCacheSize(0), fMapper(NULL)
: FontTableCache(), fSurface(surface), fPointSize(pointSize), fUnitsPerEM(0), fAscent(0), fDescent(), fLeading(0),
fDeviceScaleX(1), fDeviceScaleY(1), /*fTableCache(NULL), fTableCacheCurr(0), fTableCacheSize(0),*/ fMapper(NULL)
{
// we expect the subclass to call
// initMapper() and initFontTableCache
@ -39,12 +39,15 @@ RenderingFontInstance::RenderingFontInstance(RenderingSurface *surface, le_int16
RenderingFontInstance::~RenderingFontInstance()
{
#if 0
flushFontTableCache();
delete[] fTableCache;
#endif
delete fMapper;
}
#if 0
void RenderingFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count,
le_bool reverse, const LECharMapper *mapper, LEGlyphID glyphs[]) const
{
@ -127,32 +130,39 @@ const void *RenderingFontInstance::getFontTable(LETag tableTag) const
return fTableCache[realThis->fTableCacheCurr++].table;
};
#else
const void *RenderingFontInstance::getFontTable(LETag tableTag) const
{
return FontTableCache::find(tableTag);
}
#endif
RFIErrorCode RenderingFontInstance::initMapper()
LEErrorCode RenderingFontInstance::initMapper()
{
LETag cmapTag = 0x636D6170; // 'cmap'
const CMAPTable *cmap = (const CMAPTable *) readFontTable(cmapTag);
if (cmap == NULL) {
return RFI_MISSING_FONT_TABLE_ERROR;
return LE_MISSING_FONT_TABLE_ERROR;
}
fMapper = CMAPMapper::createUnicodeMapper(cmap);
if (fMapper == NULL) {
return RFI_MISSING_FONT_TABLE_ERROR;
return LE_MISSING_FONT_TABLE_ERROR;
}
return RFI_NO_ERROR;
return LE_NO_ERROR;
}
RFIErrorCode RenderingFontInstance::initFontTableCache()
#if 0
LEErrorCode RenderingFontInstance::initFontTableCache()
{
fTableCacheSize = TABLE_CACHE_INIT;
fTableCache = new TableCacheEntry[fTableCacheSize];
if (fTableCache == 0) {
return RFI_OUT_OF_MEMORY_ERROR;
return LE_MEMORY_ALLOCATION_ERROR;
}
for (int i = 0; i < fTableCacheSize; i += 1) {
@ -160,7 +170,7 @@ RFIErrorCode RenderingFontInstance::initFontTableCache()
fTableCache[i].table = NULL;
}
return RFI_NO_ERROR;
return LE_NO_ERROR;
}
void RenderingFontInstance::flushFontTableCache()
@ -171,3 +181,5 @@ void RenderingFontInstance::flushFontTableCache()
fTableCacheCurr = 0;
}
#endif

View file

@ -17,9 +17,12 @@
#include "LETypes.h"
#include "LEFontInstance.h"
#include "FontTableCache.h"
#include "cmaps.h"
#if 0
struct TableCacheEntry;
#endif
class RenderingFontInstance;
@ -33,6 +36,7 @@ public:
const le_int32 *dx, le_int32 x, le_int32 y, le_int32 width, le_int32 height) = 0;
};
#if 0
enum RFIErrorCode {
RFI_NO_ERROR = 0,
@ -41,8 +45,9 @@ enum RFIErrorCode {
RFI_MISSING_FONT_TABLE_ERROR = 3,
RFI_OUT_OF_MEMORY_ERROR = 4
};
#endif
class RenderingFontInstance : public LEFontInstance
class RenderingFontInstance : public LEFontInstance, protected FontTableCache
{
protected:
RenderingSurface *fSurface;
@ -56,15 +61,21 @@ protected:
float fDeviceScaleX;
float fDeviceScaleY;
#if 0
TableCacheEntry *fTableCache;
le_int32 fTableCacheCurr;
le_int32 fTableCacheSize;
#endif
CMAPMapper *fMapper;
virtual RFIErrorCode initMapper();
virtual RFIErrorCode initFontTableCache();
virtual LEErrorCode initMapper();
#if 0
virtual LEErrorCode initFontTableCache();
virtual void flushFontTableCache();
#endif
virtual const void *readFontTable(LETag tableTag) const = 0;
public:
@ -74,11 +85,15 @@ public:
virtual const void *getFontTable(LETag tableTag) const;
#if 0
virtual le_bool canDisplay(LEUnicode32 ch) const;
#endif
virtual le_int32 getUnitsPerEM() const;
#if 0
virtual le_int32 getLineHeight() const;
#endif
virtual le_int32 getAscent() const;
@ -86,9 +101,16 @@ public:
virtual le_int32 getLeading() const;
#if 0
virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, const LECharMapper *mapper, LEGlyphID glyphs[]) const;
virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const;
#endif
virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch) const
{
return fMapper->unicodeToGlyph(ch);
};
virtual le_int32 getName(le_uint16 platformID, le_uint16 scriptID, le_uint16 languageID, le_uint16 nameID, LEUnicode *name) const;
@ -100,6 +122,7 @@ public:
float getYPixelsPerEm() const;
#if 0
float xUnitsToPoints(float xUnits) const;
float yUnitsToPoints(float yUnits) const;
@ -113,22 +136,37 @@ public:
void pixelsToUnits(LEPoint &pixels, LEPoint &units) const;
void transformFunits(float xFunits, float yFunits, LEPoint &pixels) const;
#endif
float getScaleFactorX() const
{
return fDeviceScaleX;
};
float getScaleFactorY() const
{
return fDeviceScaleY;
};
};
#if 0
inline le_bool RenderingFontInstance::canDisplay(LEUnicode32 ch) const
{
return fMapper->unicodeToGlyph(ch) != 0;
}
#endif
inline le_int32 RenderingFontInstance::getUnitsPerEM() const
{
return fUnitsPerEM;
}
#if 0
inline le_int32 RenderingFontInstance::getLineHeight() const
{
return getAscent() + getDescent() + getLeading();
}
#endif
inline le_int32 RenderingFontInstance::getAscent() const
{
@ -166,6 +204,7 @@ inline float RenderingFontInstance::getYPixelsPerEm() const
return (float) fPointSize;
}
#if 0
inline float RenderingFontInstance::xUnitsToPoints(float xUnits) const
{
return (xUnits * fPointSize) / (float) fUnitsPerEM;
@ -203,5 +242,6 @@ inline void RenderingFontInstance::transformFunits(float xFunits, float yFunits,
pixels.fX = xUnitsToPoints(xFunits) * fDeviceScaleX;
pixels.fY = yUnitsToPoints(yFunits) * fDeviceScaleY;
}
#endif
#endif

View file

@ -8,6 +8,8 @@
#include "layout/LETypes.h"
#include "layout/LEFontInstance.h"
#include "unicode/locid.h"
#include "RunArrays.h"
le_int32 RunArray::ensureCapacity()
@ -83,6 +85,40 @@ const LEFontInstance *FontRuns::getFont(le_int32 run) const
return fFonts[run];
}
void LocaleRuns::init(le_int32 capacity)
{
RunArray::init(capacity);
fLocales = LE_NEW_ARRAY(const Locale *, capacity);
}
void LocaleRuns::grow(le_int32 capacity)
{
RunArray::grow(capacity);
fLocales = (const Locale **) LE_GROW_ARRAY(fLocales, capacity);
}
le_int32 LocaleRuns::add(const Locale *locale, le_int32 limit)
{
le_int32 index = RunArray::add(limit);
if (index >= 0) {
Locale **locales = (Locale **) fLocales;
locales[index] = (Locale *) locale;
}
return index;
}
const Locale *LocaleRuns::getLocale(le_int32 run) const
{
if (run < 0 || run >= getCount()) {
return NULL;
}
return fLocales[run];
}
void ValueRuns::init(le_int32 capacity)
{
RunArray::init(capacity);

View file

@ -12,13 +12,27 @@
#include "layout/LETypes.h"
#include "layout/LEFontInstance.h"
#include "unicode/locid.h"
/**
* The initial size of an array if it is unspecified.
*
* @draft ICU 2.6
*/
#define INITIAL_CAPACITY 16
/**
* When an array needs to grow, it will double in size until
* it becomes this large, then it will grow by this amount.
*
* @draft ICU 2.6
*/
#define CAPACITY_GROW_LIMIT 128
/**
* The <code>RunArray</code> class is a base class for building classes
* which represent data that is associated with runs of text. This class
* maintains an array of limit indicies into the text, subclasses
* maintains an array of limit indices into the text, subclasses
* provide one or more arrays of data.
*
* @draft ICU 2.6
@ -30,7 +44,7 @@ public:
* Construct a <code>RunArray</code> object from a pre-existing
* array of limit indices.
*
* @param limits is an array of limit indicies.
* @param limits is an array of limit indices.
*
* @param count is the number of entries in the limit array.
*
@ -40,9 +54,9 @@ public:
/**
* Construct an empty <code>RunArray</code> object. Clients can add limit
* indicies array using the <code>add</code> method.
* indices array using the <code>add</code> method.
*
* @param initialCapacity is the initial size of the limit indicies array. If
* @param initialCapacity is the initial size of the limit indices array. If
* this value is zero, no array will be allocated.
*
* @see add
@ -59,7 +73,7 @@ public:
virtual ~RunArray();
/**
* Get the number of entries in the limit indicies array.
* Get the number of entries in the limit indices array.
*
* @return the number of entries in the limit indices array.
*
@ -89,13 +103,13 @@ public:
le_int32 getLimit(le_int32 run) const;
/**
* Add a limit index to the limit indicies array and return the run index
* Add a limit index to the limit indices array and return the run index
* where it was stored. If the array does not exist, it will be created by
* calling the <code>init</code> method. If it is full, it will be grown by
* calling the <code>grow</code> method.
*
* If the <code>RunArray</code> object was created with a client-supplied
* limit indicies array, this method will return a run index of -1.
* limit indices array, 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 limit index along with whatever
@ -116,10 +130,10 @@ public:
protected:
/**
* Create a data array with the given inital size. This method will be
* called by the <code>add</code> method if there is no limit indicies
* Create a data array with the given initial size. This method will be
* called by the <code>add</code> method if there is no limit indices
* array. Subclasses which override this method must also call it from
* the overridding method to create the limit indicies array.
* the overriding method to create the limit indices array.
*
* @param capacity is the initial size of the data array.
*
@ -130,10 +144,10 @@ protected:
virtual void init(le_int32 capacity);
/**
* Grow a data array to the given inital size. This method will be
* called by the <code>add</code> method if the limit indicies
* Grow a data array to the given initial size. This method will be
* called by the <code>add</code> method if the limit indices
* array is full. Subclasses which override this method must also call it from
* the overridding method to grow the limit indicies array.
* the overriding method to grow the limit indices array.
*
* @param capacity is the initial size of the data array.
*
@ -212,11 +226,11 @@ class FontRuns : public RunArray
public:
/**
* Construct a <code>FontRuns</code> object from pre-existing arrays of fonts
* and limit indicies.
* and limit indices.
*
* @param fonts is the address of an array of pointers to <code>LEFontInstance</code> objects.
*
* @param limits is the address of an array of limit indicies.
* @param limits is the address of an array of limit indices.
*
* @param count is the number of entries in the two arrays.
*
@ -226,9 +240,9 @@ public:
/**
* Construct an empty <code>FontRuns</code> object. Clients can add font and limit
* indicies arrays using the <code>add</code> method.
* indices arrays using the <code>add</code> method.
*
* @param initialCapacity is the initial size of the font and limit indicies arrays. If
* @param initialCapacity is the initial size of the font and limit indices arrays. If
* this value is zero, no arrays will be allocated.
*
* @see add
@ -249,7 +263,7 @@ public:
* of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
* limit index.
*
* @param run is the index into the font and limit indicies arrays.
* @param run is the index into the font and limit indices arrays.
*
* @return the <code>LEFontInstance</code> associated with the given text run.
*
@ -266,11 +280,11 @@ public:
* <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
*
* If the <code>FontRuns</code> object was created with a client-supplied
* font and limit indicies arrays, this method will return a run index of -1.
* font 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 font 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 indicies
* 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 font is the address of the <code>LEFontInstance</code> to add
@ -314,6 +328,119 @@ inline FontRuns::~FontRuns()
}
}
/**
* The <code>LocaleRuns</code> class associates pointers to <code>Locale</code>
* objects with runs of text.
*
* @draft ICU 2.6
*/
class LocaleRuns : public RunArray
{
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 pointers to <code>Locale</code> objects.
*
* @param limits is the address of an array of limit indices.
*
* @param count is the number of entries in the two arrays.
*
* @draft ICU 2.6
*/
LocaleRuns(const Locale **locales, const le_int32 *limits, le_int32 count);
/**
* Construct an empty <code>LocaleRuns</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 2.6
*/
LocaleRuns(le_int32 initialCapacity);
/**
* The destructor; virtual so that subclass destructors are invoked as well.
*
* @draft ICU 2.6
*/
virtual ~LocaleRuns();
/**
* Get the <code>Locale</code> object 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 <code>Locale</code> associated with the given text run.
*
* @see RunArray::getLimit
*
* @draft ICU 2.6
*/
const Locale *getLocale(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>LocaleRuns</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 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 address of the <code>Locale</code> to add
*
* @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 2.6
*/
le_int32 add(const Locale *locale, le_int32 limit);
protected:
virtual void init(le_int32 capacity);
virtual void grow(le_int32 capacity);
private:
const Locale **fLocales;
};
inline LocaleRuns::LocaleRuns(const Locale **locales, const le_int32 *limits, le_int32 count)
: RunArray(limits, count), fLocales(locales)
{
// nothing else to do...
}
inline LocaleRuns::LocaleRuns(le_int32 initialCapacity)
: RunArray(initialCapacity), fLocales(NULL)
{
if (initialCapacity > 0) {
fLocales = LE_NEW_ARRAY(const Locale *, initialCapacity);
}
}
inline LocaleRuns::~LocaleRuns()
{
if (! fClientArrays) {
LE_DELETE_ARRAY(fLocales);
fLocales = NULL;
}
}
/**
* The <code>ValueRuns</code> class associates integer values with runs of text.
*
@ -324,11 +451,11 @@ class ValueRuns : public RunArray
public:
/**
* Construct a <code>ValueRuns</code> object from pre-existing arrays of values
* and limit indicies.
* and limit indices.
*
* @param values is the address of an array of integer.
*
* @param limits is the address of an array of limit indicies.
* @param limits is the address of an array of limit indices.
*
* @param count is the number of entries in the two arrays.
*
@ -338,9 +465,9 @@ public:
/**
* Construct an empty <code>ValueRuns</code> object. Clients can add value and limit
* indicies arrays using the <code>add</code> method.
* indices arrays using the <code>add</code> method.
*
* @param initialCapacity is the initial size of the value and limit indicies arrays. If
* @param initialCapacity is the initial size of the value and limit indices arrays. If
* this value is zero, no arrays will be allocated.
*
* @see add
@ -361,7 +488,7 @@ public:
* of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
* limit index.
*
* @param run is the index into the font and limit indicies arrays.
* @param run is the index into the font and limit indices arrays.
*
* @return the integer value associated with the given text run.
*
@ -378,11 +505,11 @@ public:
* <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
*
* If the <code>ValueRuns</code> object was created with a client-supplied
* font and limit indicies arrays, this method will return a run index of -1.
* font 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 an integer value 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 indicies
* 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 value is the integer value to add

View file

@ -163,7 +163,7 @@ Paragraph::Paragraph(const LEUnicode chars[], int32_t charCount, const FontRuns
: fParagraphLayout(NULL), fLineCount(0), fLinesMax(0), fLinesGrow(LINE_GROW), fLines(NULL),
fLineHeight(-1), fAscent(-1), fWidth(-1), fHeight(-1)
{
fParagraphLayout = new ParagraphLayout(chars, charCount, fontRuns, NULL, NULL, UBIDI_LTR, false);
fParagraphLayout = new ParagraphLayout(chars, charCount, fontRuns, NULL, NULL, NULL, UBIDI_LTR, false);
le_int32 ascent = fParagraphLayout->getAscent();
le_int32 descent = fParagraphLayout->getDescent();