mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-19 03:34:38 +00:00
ICU-2253 Add LocaleRuns, preliminary code to map Locale to LanguageCode.
X-SVN-Rev: 11635
This commit is contained in:
parent
d84ed8d5fa
commit
841771c66d
7 changed files with 401 additions and 69 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue