2002-12-13 22:39:33 +00:00
|
|
|
/*
|
|
|
|
**********************************************************************
|
|
|
|
* Copyright (C) 2002, International Business Machines
|
|
|
|
* Corporation and others. All Rights Reserved.
|
|
|
|
**********************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __PARAGRAPHLAYOUT_H
|
|
|
|
|
|
|
|
#define __PARAGRAPHLAYOUT_H
|
|
|
|
|
|
|
|
#include "layout/LETypes.h"
|
|
|
|
#include "layout/LayoutEngine.h"
|
|
|
|
#include "layout/LEFontInstance.h"
|
|
|
|
#include "unicode/ubidi.h"
|
|
|
|
#include "unicode/brkiter.h"
|
|
|
|
|
|
|
|
struct VisualRunInfo;
|
|
|
|
struct StyleRunInfo;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ParagraphLayout.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* 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...
|
|
|
|
*
|
|
|
|
* * Need a usage example, esp. to show that you need to call findLineBreak() before
|
|
|
|
* countLineRuns() and / or getVisualRun(). (AND, what should happen if you don't??)
|
|
|
|
* (It treats the whole paragraph as a single line.)
|
|
|
|
*
|
|
|
|
* If you don't call countLineRuns() before getVisualRun(), we'll (effectively) call
|
|
|
|
* it internally.
|
|
|
|
*
|
|
|
|
* * Might want to change to a model where a paragraph object iterates over lines objects
|
|
|
|
* and a line object iterates over runs.
|
2002-12-13 22:41:39 +00:00
|
|
|
*
|
|
|
|
* * 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.
|
2002-12-13 22:39:33 +00:00
|
|
|
*
|
|
|
|
* * May need to handle composite fonts via LEFontInstance. We'd get a 32-bit glyph ID
|
|
|
|
* back from mapCharToGlyph() where the high 16 bits identify the physical font. We'd
|
|
|
|
* need to use this to compute physical font runs. Might want to make some of the high
|
|
|
|
* bits be client-defined flags, which the LayoutEngine will always ignore. Say 8 bits
|
|
|
|
* of flags, and 8 bits of font ID. (The flags could be used by clients for whatever they
|
|
|
|
* want, we wouldn't look at them at all...)
|
|
|
|
*
|
|
|
|
* * Might want language (or maybe locale?) runs in the constructor so that language tags
|
|
|
|
* can be passed to the LayoutEngines.
|
|
|
|
*/
|
|
|
|
class ParagraphLayout
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Construct a <code>ParagraphLayout</code> object for a styled paragraph. The paragraph is specified
|
|
|
|
* as runs of text all in the same font. An <code>LEFontInstance</code> object and a limit offset
|
|
|
|
* are specified for each font run. The limit offset is the offset of the character immediately
|
|
|
|
* after the font run.
|
|
|
|
*
|
|
|
|
* Clients can optionally specify directional runs and / or script runs. If these aren't specified
|
|
|
|
* they will be computed.
|
|
|
|
*
|
|
|
|
* @param chars is an array of the characters in the paragraph
|
|
|
|
*
|
|
|
|
* @param count is the number of characters in the paragraph.
|
|
|
|
*
|
|
|
|
* @param fonts is an array of the <code>LEFontInstance</code> objects associated
|
|
|
|
* with each font run.
|
|
|
|
*
|
|
|
|
* @param fontRunLimits is an array of the run limits of each font run.
|
|
|
|
*
|
|
|
|
* @param fontRunCount is the number of font runs.
|
|
|
|
*
|
|
|
|
* @param levels is an array of directional levels. If this pointer in <code>NULL</code>
|
|
|
|
* the levels will be determined by running the Unicde Bidi algorithm.
|
|
|
|
*
|
|
|
|
* @param levelRunLimits is an array of run limits for each level run. If <code>levels</code>
|
|
|
|
* is <code>NULL</code> this pointer must be <code>NULL</code> too.
|
|
|
|
*
|
|
|
|
* @param levelRunCount is the number of directional level runs. If <code>levels</code> is
|
|
|
|
* <code>NULL</code> this count must be zero.
|
|
|
|
*
|
|
|
|
* @param scripts is an array of script codes. If this pointer in <code>NULL</code>
|
|
|
|
* the script runs will be determined using the Unicode code points.
|
|
|
|
*
|
|
|
|
* @param scriptRunLimits is an array of run limits for each script run. If <code>scripts</code>
|
|
|
|
* is <code>NULL</code> this pointer must be <code>NULL</code> too.
|
|
|
|
*
|
|
|
|
* @param scriptRunCount is the number of script runs. If <code>scripts</code> is
|
|
|
|
* <code>NULL</code> this count must be zero.
|
|
|
|
*
|
|
|
|
* @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.
|
|
|
|
*
|
|
|
|
* @see ubidi.h
|
|
|
|
* @see LEFontInstance.h
|
|
|
|
* @see LayoutEngine.h
|
|
|
|
*
|
|
|
|
* @draft
|
|
|
|
*/
|
|
|
|
ParagraphLayout(const LEUnicode chars[], le_int32 count,
|
|
|
|
const LEFontInstance **fonts, const le_int32 fontRunLimits[], le_int32 fontRunCount,
|
|
|
|
const UBiDiLevel levels[], const le_int32 levelRunLimits[], le_int32 levelRunCount,
|
|
|
|
const UScriptCode scripts[], const le_int32 scriptRunLimits[], le_int32 scriptRunCount,
|
|
|
|
UBiDiLevel paragraphLevel, le_bool vertical);
|
|
|
|
|
|
|
|
~ParagraphLayout();
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/**
|
|
|
|
* Examine the given styled paragraph and determine if it contains any text which
|
|
|
|
* requires complex processing. (i.e. that cannot be correctly rendered by
|
|
|
|
* just mapping the characters to glyphs and rendering them in order)
|
|
|
|
*
|
|
|
|
* @param chars is an array of the characters in the paragraph
|
|
|
|
*
|
|
|
|
* @param count is the number of characters in the paragraph.
|
|
|
|
*
|
|
|
|
* @param fonts is an array of the <code>LEFontInstance</code> objects associated
|
|
|
|
* with each font run.
|
|
|
|
*
|
|
|
|
* @param fontRunLimits is an array of the run limits of each font run.
|
|
|
|
*
|
|
|
|
* @param fontRunCount is the number of font runs.
|
|
|
|
*
|
|
|
|
* @return <code>true</code> if the paragraph contains complex text.
|
|
|
|
*/
|
|
|
|
static le_bool isComplex(const LEUnicode chars[], le_int32 count,
|
|
|
|
const LEFontInstance *fonts[], const le_int32 fontRunLimits[], le_int32 fontRunCount);
|
|
|
|
#else
|
|
|
|
/**
|
|
|
|
* Examine the given text and determine if it contains characters in any
|
|
|
|
* script which requires complex processing to be rendered correctly.
|
|
|
|
*
|
|
|
|
* @param chars is an array of the characters in the paragraph
|
|
|
|
*
|
|
|
|
* @param count is the number of characters in the paragraph.
|
|
|
|
*
|
|
|
|
* @return <code>true</code> if any of the text requires complex processing.
|
|
|
|
*/
|
|
|
|
static le_bool isComplex(const LEUnicode chars[], le_int32 count);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the resolved paragraph level. This is useful for those cases
|
|
|
|
* where the bidi analysis has determined the level based on the first
|
|
|
|
* strong character in the paragraph.
|
|
|
|
*
|
|
|
|
* @return the resolved paragraph level.
|
|
|
|
*/
|
|
|
|
UBiDiLevel getParagraphLevel();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the directionality of the text in the paragraph.
|
|
|
|
*
|
|
|
|
* @return <code>UBIDI_LTR</code> if the text is all left to right,
|
|
|
|
* <code>UBIDI_RTL</code> if the text is all right to left,
|
|
|
|
* or <code>UBIDI_MIXED</code> if the text has mixed direction.
|
|
|
|
*/
|
|
|
|
UBiDiDirection getTextDirection();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reset line breaking to start from the beginning of the paragraph.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void reflow();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find the next line in the paragraph. The width of the line is specified
|
|
|
|
* each time so that it can be varied to support arbitrary paragraph shapes.
|
|
|
|
*
|
|
|
|
* @param width is the width of the line.
|
|
|
|
*
|
|
|
|
* @return the offset of the first character which will not fit on the line, or -1
|
|
|
|
* if there are no more lines in the paragraph.
|
|
|
|
*/
|
|
|
|
le_int32 nextLineBreak(float width);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Count the number of runs in the line. Each run will contain glyphs
|
|
|
|
* in the same font and direction.
|
|
|
|
*
|
|
|
|
* @return the number of runs on the line.
|
|
|
|
*/
|
|
|
|
le_int32 countLineRuns();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the glyphs in the a visual run of the current line.
|
|
|
|
*
|
|
|
|
* @param runIndex is the index of the run.
|
|
|
|
*
|
|
|
|
* @param glyphs is an array which will receive the glyphs in the run, in visual order. If this
|
|
|
|
* is <code>NULL</code>, no glyphs are retreived.
|
|
|
|
*
|
|
|
|
* @param positions is an array which will receive the x and y position for
|
|
|
|
* each glyph in the run. This array will contain two entries for each glyph. The entry
|
|
|
|
* at the even offset will be the x position of the glyph, and the entry at the following
|
|
|
|
* odd offset will be the y position. There will be an extra pair of positions at the end
|
|
|
|
* of the array to specify the position of the glyph following the run. If this is <code>NULL</code>
|
|
|
|
* no positions are stored.
|
|
|
|
*
|
|
|
|
* @param glyphToCharMap is an array which will receive the original character offset for each glyph
|
|
|
|
* in the run. If this is <code>NULL</code> no character offsets are stored.
|
|
|
|
*
|
|
|
|
* @param font will receive the <code>LEFontInstance</code> object associated with this run.
|
|
|
|
*
|
|
|
|
* @param runLevel will receive the run direction.
|
|
|
|
*
|
|
|
|
* @return the number of glyphs in the run, or -1 if <code>runIndex</code> is out or range.
|
|
|
|
*
|
|
|
|
* NOTE: All input arrays are owned by the Caller. You can call this method with <code>glyphs</code>,
|
|
|
|
* <code>advances</code>, and <code>glyphToCharMap</code> all set to <code>NULL</code> to get the number
|
|
|
|
* of glyphs in the run, allocate the arrays, and call this method again to fill the arrays.
|
|
|
|
*/
|
|
|
|
le_int32 getVisualRun(le_int32 runIndex, LEGlyphID glyphs[], float positions[], le_int32 glyphToCharMap[],
|
|
|
|
const LEFontInstance **font, UBiDiDirection *runDirection);
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
void computeLevels(UBiDiLevel paragraphLevel);
|
|
|
|
|
|
|
|
void computeVisualRuns();
|
|
|
|
|
|
|
|
void computeScripts();
|
|
|
|
|
|
|
|
le_int32 getCharRun(le_int32 charIndex);
|
|
|
|
|
|
|
|
static le_bool isComplex(UScriptCode script);
|
|
|
|
|
|
|
|
le_int32 previousBreak(le_int32 charIndex);
|
|
|
|
|
|
|
|
|
|
|
|
const LEUnicode *fChars;
|
|
|
|
le_int32 fCharCount;
|
|
|
|
|
|
|
|
const LEFontInstance **fFonts;
|
|
|
|
const le_int32 *fFontRunLimits;
|
|
|
|
le_int32 fFontRunCount;
|
|
|
|
|
|
|
|
const UBiDiLevel *fLevels;
|
|
|
|
const le_int32 *fLevelRunLimits;
|
|
|
|
le_int32 fLevelRunCount;
|
|
|
|
|
|
|
|
const UScriptCode *fScripts;
|
|
|
|
const le_int32 *fScriptRunLimits;
|
|
|
|
le_int32 fScriptRunCount;
|
|
|
|
|
|
|
|
le_bool fVertical;
|
|
|
|
le_bool fClientLevels;
|
|
|
|
le_bool fClientScripts;
|
|
|
|
|
|
|
|
UBiDiLevel *fEmbeddingLevels;
|
|
|
|
|
|
|
|
le_int32 *fGlyphToCharMap;
|
|
|
|
le_int32 *fCharToGlyphMap;
|
|
|
|
float *fGlyphWidths;
|
|
|
|
le_int32 fGlyphCount;
|
|
|
|
|
|
|
|
UBiDi *fParaBidi;
|
|
|
|
UBiDi *fLineBidi;
|
|
|
|
|
|
|
|
le_int32 *fStyleRunLimits;
|
|
|
|
le_int32 *fStyleIndices;
|
|
|
|
StyleRunInfo *fStyleRunInfo;
|
|
|
|
le_int32 fStyleRunCount;
|
|
|
|
|
|
|
|
BreakIterator *fBreakIterator;
|
|
|
|
le_int32 fLineStart;
|
|
|
|
le_int32 fLineEnd;
|
|
|
|
|
|
|
|
VisualRunInfo *fVisualRuns;
|
|
|
|
le_int32 fVisualRunCount;
|
|
|
|
le_int32 fFirstVisualRun;
|
|
|
|
le_int32 fLastVisualRun;
|
|
|
|
float fVisualRunLastX;
|
|
|
|
float fVisualRunLastY;
|
|
|
|
|
|
|
|
static le_bool fComplexTable[];
|
|
|
|
};
|
|
|
|
|
|
|
|
inline UBiDiLevel ParagraphLayout::getParagraphLevel()
|
|
|
|
{
|
|
|
|
return ubidi_getParaLevel(fParaBidi);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline UBiDiDirection ParagraphLayout::getTextDirection()
|
|
|
|
{
|
|
|
|
return ubidi_getDirection(fParaBidi);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void ParagraphLayout::reflow()
|
|
|
|
{
|
|
|
|
fLineEnd = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|