/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsBidi_ICU_h__
#define nsBidi_ICU_h__
#include "unicode/ubidi.h"
#include "nsIFrame.h" // for nsBidiLevel/nsBidiDirection declarations
// nsBidi implemented as a simple wrapper around the bidi reordering engine
// from ICU.
// We could eliminate this and let callers use the ICU functions directly
// once we no longer care about building without ICU available.
class nsBidi
{
public:
/** @brief Default constructor.
*
* The nsBidi object is initially empty. It is assigned
* the Bidi properties of a paragraph by SetPara()
.
*/
explicit nsBidi();
/** @brief Destructor. */
virtual ~nsBidi();
/**
* Perform the Unicode Bidi algorithm.
*
* @param aText is a pointer to the single-paragraph text that the
* Bidi algorithm will be performed on
* (step (P1) of the algorithm is performed externally).
* The text must be (at least) aLength
long.
*
* @param aLength is the length of the text; if aLength==-1
then
* the text must be zero-terminated.
*
* @param aParaLevel specifies the default level for the paragraph;
* it is typically 0 (LTR) or 1 (RTL).
* If the function shall determine the paragraph level from the text,
* then aParaLevel
can be set to
* either NSBIDI_DEFAULT_LTR
* or NSBIDI_DEFAULT_RTL
;
* if there is no strongly typed character, then
* the desired default is used (0 for LTR or 1 for RTL).
* Any other value between 0 and NSBIDI_MAX_EXPLICIT_LEVEL
* is also valid, with odd levels indicating RTL.
*/
nsresult SetPara(const char16_t *aText, int32_t aLength,
nsBidiLevel aParaLevel);
/**
* Get the directionality of the text.
*
* @param aDirection receives a NSBIDI_XXX
value that indicates
* if the entire text represented by this object is unidirectional,
* and which direction, or if it is mixed-directional.
*
* @see nsBidiDirection
*/
nsresult GetDirection(nsBidiDirection* aDirection);
/**
* Get the paragraph level of the text.
*
* @param aParaLevel receives a NSBIDI_XXX
value indicating
* the paragraph level
*
* @see nsBidiLevel
*/
nsresult GetParaLevel(nsBidiLevel* aParaLevel);
/**
* Get a logical run.
* This function returns information about a run and is used
* to retrieve runs in logical order.
* This is especially useful for line-breaking on a paragraph.
*
* @param aLogicalStart is the first character of the run.
*
* @param aLogicalLimit will receive the limit of the run.
* The l-value that you point to here may be the
* same expression (variable) as the one for
* aLogicalStart
.
* This pointer can be nullptr
if this
* value is not necessary.
*
* @param aLevel will receive the level of the run.
* This pointer can be nullptr
if this
* value is not necessary.
*/
nsresult GetLogicalRun(int32_t aLogicalStart, int32_t* aLogicalLimit,
nsBidiLevel* aLevel);
/**
* Get the number of runs.
* This function may invoke the actual reordering on the
* nsBidi
object, after SetPara
* may have resolved only the levels of the text. Therefore,
* CountRuns
may have to allocate memory,
* and may fail doing so.
*
* @param aRunCount will receive the number of runs.
*/
nsresult CountRuns(int32_t* aRunCount);
/**
* Get one run's logical start, length, and directionality,
* which can be 0 for LTR or 1 for RTL.
* In an RTL run, the character at the logical start is
* visually on the right of the displayed run.
* The length is the number of characters in the run.
* CountRuns
should be called
* before the runs are retrieved.
*
* @param aRunIndex is the number of the run in visual order, in the
* range [0..CountRuns-1]
.
*
* @param aLogicalStart is the first logical character index in the text.
* The pointer may be nullptr
if this index is not needed.
*
* @param aLength is the number of characters (at least one) in the run.
* The pointer may be nullptr
if this is not needed.
*
* @param aDirection will receive the directionality of the run,
* NSBIDI_LTR==0
or NSBIDI_RTL==1
,
* never NSBIDI_MIXED
.
*
* @see CountRuns
*
* Example:
* @code
* int32_t i, count, logicalStart, visualIndex=0, length;
* nsBidiDirection dir;
* pBidi->CountRuns(&count);
* for(i=0; i
* The index map will result in
* GetVisualMap
on a
* nsBidi
object.
*
* @param aLevels is an array with aLength
levels that have been
* determined by the application.
*
* @param aLength is the number of levels in the array, or, semantically,
* the number of objects to be reordered.
* It must be aLength>0
.
*
* @param aIndexMap is a pointer to an array of aLength
* indexes which will reflect the reordering of the characters.
* The array does not need to be initialized.aIndexMap[aVisualIndex]==aLogicalIndex
.
*/
static nsresult ReorderVisual(const nsBidiLevel* aLevels, int32_t aLength,
int32_t* aIndexMap);
private:
nsBidi(const nsBidi&) = delete;
void operator=(const nsBidi&) = delete;
protected:
UBiDi* mBiDi;
};
#endif // _nsBidi_ICU_h_