
/*
 *
 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
 *
 */

#ifndef __LAYOUTENGINE_H
#define __LAYOUTENGINE_H

#include "LETypes.h"

/**
 * \file 
 * \brief C++ API: Virtual base class for complex text layout.
 */

U_NAMESPACE_BEGIN

class LEFontInstance;
class LEGlyphFilter;
class LEGlyphStorage;

/**
 * This is a virtual base class used to do complex text layout. The text must all
 * be in a single font, script, and language. An instance of a LayoutEngine can be
 * created by calling the layoutEngineFactory method. Fonts are identified by
 * instances of the LEFontInstance class. Script and language codes are identified
 * by integer codes, which are defined in ScriptAndLanuageTags.h.
 *
 * Note that this class is not public API. It is declared public so that it can be
 * exported from the library that it is a part of.
 *
 * The input to the layout process is an array of characters in logical order,
 * and a starting X, Y position for the text. The output is an array of glyph indices,
 * an array of character indices for the glyphs, and an array of glyph positions.
 * These arrays are protected members of LayoutEngine which can be retreived by a
 * public method. The reset method can be called to free these arrays so that the
 * LayoutEngine can be reused.
 *
 * The layout process is done in three steps. There is a protected virtual method
 * for each step. These methods have a default implementation which only does
 * character to glyph mapping and default positioning using the glyph's advance
 * widths. Subclasses can override these methods for more advanced layout.
 * There is a public method which invokes the steps in the correct order.
 * 
 * The steps are:
 *
 * 1) Glyph processing - character to glyph mapping and any other glyph processing
 *    such as ligature substitution and contextual forms.
 *
 * 2) Glyph positioning - position the glyphs based on their advance widths.
 *
 * 3) Glyph position adjustments - adjustment of glyph positions for kerning,
 *    accent placement, etc.
 *
 * NOTE: in all methods below, output parameters are references to pointers so
 * the method can allocate and free the storage as needed. All storage allocated
 * in this way is owned by the object which created it, and will be freed when it
 * is no longer needed, or when the object's destructor is invoked.
 *
 * @see LEFontInstance
 * @see ScriptAndLanguageTags.h
 *
 * @stable ICU 2.8
 */
class U_LAYOUT_API LayoutEngine : public UObject {
protected:
    /**
     * The object which holds the glyph storage
     *
     * @internal
     */
    LEGlyphStorage *fGlyphStorage;

    /**
     * The font instance for the text font.
     *
     * @see LEFontInstance
     *
     * @internal
     */
    const LEFontInstance *fFontInstance;

    /**
     * The script code for the text
     *
     * @see ScriptAndLanguageTags.h for script codes.
     *
     * @internal
     */
    le_int32 fScriptCode;

    /**
     * The langauge code for the text
     *
     * @see ScriptAndLanguageTags.h for language codes.
     *
     * @internal
     */
    le_int32 fLanguageCode;

    /**
     * The typographic control flags
     *
     * @internal
     */
    le_int32 fTypoFlags;

    /**
     * This constructs an instance for a given font, script and language. Subclass constructors
     * must call this constructor.
     *
     * @param fontInstance - the font for the text
     * @param scriptCode - the script for the text
     * @param languageCode - the language for the text
     * @param typoFlags - the typographic control flags for the text.  Set bit 1 if kerning
     * is desired, set bit 2 if ligature formation is desired.  Others are reserved.
     *
     * @see LEFontInstance
     * @see ScriptAndLanguageTags.h
     *
     * @internal
     */
    LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags);

    /**
     * This overrides the default no argument constructor to make it
     * difficult for clients to call it. Clients are expected to call
     * layoutEngineFactory.
     *
     * @internal
     */
    LayoutEngine();

    /**
     * This method does any required pre-processing to the input characters. It
     * may generate output characters that differ from the input charcters due to
     * insertions, deletions, or reorderings. In such cases, it will also generate an
     * output character index array reflecting these changes.
     *
     * Subclasses must override this method.
     *
     * Input parameters:
     * @param chars - the input character context
     * @param offset - the index of the first character to process
     * @param count - the number of characters to process
     * @param max - the number of characters in the input context
     * @param rightToLeft - TRUE if the characters are in a right to left directional run
     * @param outChars - the output character array, if different from the input
     * @param glyphStorage - the object that holds the per-glyph storage. The character index array may be set.
     * @param success - set to an error code if the operation fails
     *
     * @return the output character count (input character count if no change)
     *
     * @internal
     */
    virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
            LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success);

    /**
     * This method does the glyph processing. It converts an array of characters
     * into an array of glyph indices and character indices. The characters to be
     * processed are passed in a surrounding context. The context is specified as
     * a starting address and a maximum character count. An offset and a count are
     * used to specify the characters to be processed.
     *
     * The default implementation of this method only does character to glyph mapping.
     * Subclasses needing more elaborate glyph processing must override this method.
     *
     * Input parameters:
     * @param chars - the character context
     * @param offset - the offset of the first character to process
     * @param count - the number of characters to process
     * @param max - the number of characters in the context.
     * @param rightToLeft - TRUE if the text is in a right to left directional run
     * @param glyphStorage - the object which holds the per-glyph storage. The glyph and char indices arrays
     *                       will be set.
     *
     * Output parameters:
     * @param success - set to an error code if the operation fails
     *
     * @return the number of glyphs in the glyph index array
     *
     * @internal
     */
    virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success);

    /**
     * This method does basic glyph positioning. The default implementation positions
     * the glyphs based on their advance widths. This is sufficient for most uses. It
     * is not expected that many subclasses will override this method.
     *
     * Input parameters:
     * @param glyphStorage - the object which holds the per-glyph storage. The glyph position array will be set.
     * @param x - the starting X position
     * @param y - the starting Y position
     * @param success - set to an error code if the operation fails
     *
     * @internal
     */
    virtual void positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y, LEErrorCode &success);

    /**
     * This method does positioning adjustments like accent positioning and
     * kerning. The default implementation does nothing. Subclasses needing
     * position adjustments must override this method.
     *
     * Note that this method has both characters and glyphs as input so that
     * it can use the character codes to determine glyph types if that information
     * isn't directly available. (e.g. Some Arabic OpenType fonts don't have a GDEF
     * table)
     *
     * @param chars - the input character context
     * @param offset - the offset of the first character to process
     * @param count - the number of characters to process
     * @param reverse - <code>TRUE</code> if the glyphs in the glyph array have been reordered
     * @param glyphStorage - the object which holds the per-glyph storage. The glyph positions will be
     *                       adjusted as needed.
     * @param success - output parameter set to an error code if the operation fails
     *
     * @internal
     */
    virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, LEGlyphStorage &glyphStorage, LEErrorCode &success);

    /**
     * This method gets a table from the font associated with
     * the text. The default implementation gets the table from
     * the font instance. Subclasses which need to get the tables
     * some other way must override this method.
     * 
     * @param tableTag - the four byte table tag.
     *
     * @return the address of the table.
     *
     * @internal
     */
    virtual const void *getFontTable(LETag tableTag) const;

    /**
     * This method does character to glyph mapping. The default implementation
     * uses the font instance to do the mapping. It will allocate the glyph and
     * character index arrays if they're not already allocated. If it allocates the
     * character index array, it will fill it it.
     *
     * This method supports right to left
     * text with the ability to store the glyphs in reverse order, and by supporting
     * character mirroring, which will replace a character which has a left and right
     * form, such as parens, with the opposite form before mapping it to a glyph index.
     *
     * Input parameters:
     * @param chars - the input character context
     * @param offset - the offset of the first character to be mapped
     * @param count - the number of characters to be mapped
     * @param reverse - if <code>TRUE</code>, the output will be in reverse order
     * @param mirror - if <code>TRUE</code>, do character mirroring
     * @param filterZeroWidth - if <code>TRUE</code> replace ZWJ / ZWNJ with a glyph with no contours.
     * @param glyphStorage - the object which holds the per-glyph storage. The glyph and char
     *                       indices arrays will be filled in.
     * @param success - set to an error code if the operation fails
     *
     * @see LEFontInstance
     *
     * @internal
     */
    virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage, LEErrorCode &success);

    /**
     * This is a convenience method that forces the advance width of mark
     * glyphs to be zero, which is required for proper selection and highlighting.
     * 
     * @param glyphStorage - the object containing the per-glyph storage. The positions array will be modified.
     * @param markFilter - used to identify mark glyphs
     * @param success - output parameter set to an error code if the operation fails
     *
     * @see LEGlyphFilter
     *
     * @internal
     */
    static void adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success);


    /**
     * This is a convenience method that forces the advance width of mark
     * glyphs to be zero, which is required for proper selection and highlighting.
     * This method uses the input characters to identify marks. This is required in
     * cases where the font does not contain enough information to identify them based
     * on the glyph IDs.
     * 
     * @param chars - the array of input characters
     * @param charCount - the number of input characers
     * @param glyphStorage - the object containing the per-glyph storage. The positions array will be modified.
     * @param reverse - <code>TRUE</code> if the glyph array has been reordered
     * @param markFilter - used to identify mark glyphs
     * @param success - output parameter set to an error code if the operation fails
     *
     * @see LEGlyphFilter
     *
     * @internal
     */
    static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success);


public:
    /**
     * The destructor. It will free any storage allocated for the
     * glyph, character index and position arrays by calling the reset
     * method. It is declared virtual so that it will be invoked by the
     * subclass destructors.
     *
     * @stable ICU 2.8
     */
    virtual ~LayoutEngine();

    /**
     * This method will invoke the layout steps in their correct order by calling
     * the computeGlyphs, positionGlyphs and adjustGlyphPosition methods.. It will
     * compute the glyph, character index and position arrays.
     *
     * @param chars - the input character context
     * @param offset - the offset of the first character to process
     * @param count - the number of characters to process
     * @param max - the number of characters in the input context
     * @param rightToLeft - TRUE if the characers are in a right to left directional run
     * @param x - the initial X position
     * @param y - the initial Y position
     * @param success - output parameter set to an error code if the operation fails
     *
     * @return the number of glyphs in the glyph array
     *
     * Note; the glyph, character index and position array can be accessed
     * using the getter method below.
     *
     * @stable ICU 2.8
     */
    virtual le_int32 layoutChars(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, float x, float y, LEErrorCode &success);

    /**
     * This method returns the number of glyphs in the glyph array. Note
     * that the number of glyphs will be greater than or equal to the number
     * of characters used to create the LayoutEngine.
     *
     * @return the number of glyphs in the glyph array
     *
     * @stable ICU 2.8
     */
    le_int32 getGlyphCount() const;

    /**
     * This method copies the glyph array into a caller supplied array.
     * The caller must ensure that the array is large enough to hold all
     * the glyphs.
     *
     * @param glyphs - the destiniation glyph array
     * @param success - set to an error code if the operation fails
     *
     * @stable ICU 2.8
     */
    void getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const;

    /**
     * This method copies the glyph array into a caller supplied array,
     * ORing in extra bits. (This functionality is needed by the JDK,
     * which uses 32 bits pre glyph idex, with the high 16 bits encoding
     * the composite font slot number)
     *
     * @param glyphs - the destination (32 bit) glyph array
     * @param extraBits - this value will be ORed with each glyph index
     * @param success - set to an error code if the operation fails
     *
     * @stable ICU 2.8
     */
    virtual void getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const;

    /**
     * This method copies the character index array into a caller supplied array.
     * The caller must ensure that the array is large enough to hold a
     * character index for each glyph.
     *
     * @param charIndices - the destiniation character index array
     * @param success - set to an error code if the operation fails
     *
     * @stable ICU 2.8
     */
    void getCharIndices(le_int32 charIndices[], LEErrorCode &success) const;

    /**
     * This method copies the character index array into a caller supplied array.
     * The caller must ensure that the array is large enough to hold a
     * character index for each glyph.
     *
     * @param charIndices - the destiniation character index array
     * @param indexBase - an offset which will be added to each index
     * @param success - set to an error code if the operation fails
     *
     * @stable ICU 2.8
     */
    void getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const;

    /**
     * This method copies the position array into a caller supplied array.
     * The caller must ensure that the array is large enough to hold an
     * X and Y position for each glyph, plus an extra X and Y for the
     * advance of the last glyph.
     *
     * @param positions - the destiniation position array
     * @param success - set to an error code if the operation fails
     *
     * @stable ICU 2.8
     */
    void getGlyphPositions(float positions[], LEErrorCode &success) const;

    /**
     * This method returns the X and Y position of the glyph at
     * the given index.
     *
     * Input parameters:
     * @param glyphIndex - the index of the glyph
     *
     * Output parameters:
     * @param x - the glyph's X position
     * @param y - the glyph's Y position
     * @param success - set to an error code if the operation fails
     *
     * @stable ICU 2.8
     */
    void getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const;

    /**
     * This method frees the glyph, character index and position arrays
     * so that the LayoutEngine can be reused to layout a different
     * characer array. (This method is also called by the destructor)
     *
     * @stable ICU 2.8
     */
    virtual void reset();

    /**
     * This method returns a LayoutEngine capable of laying out text
     * in the given font, script and langauge. Note that the LayoutEngine
     * returned may be a subclass of LayoutEngine.
     *
     * @param fontInstance - the font of the text
     * @param scriptCode - the script of the text
     * @param languageCode - the language of the text
     * @param success - output parameter set to an error code if the operation fails
     *
     * @return a LayoutEngine which can layout text in the given font.
     *
     * @see LEFontInstance
     *
     * @stable ICU 2.8
     */
    static LayoutEngine *layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success);

    /**
     * Override of existing call that provides flags to control typography.
     * @draft ICU 3.4
     */
    static LayoutEngine *layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typo_flags, LEErrorCode &success);

    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @stable ICU 2.8
     */
    virtual UClassID getDynamicClassID() const;

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @stable ICU 2.8
     */
    static UClassID getStaticClassID();

};

U_NAMESPACE_END
#endif

