
/*
 * %W% %E%
 *
 * (C) Copyright IBM Corp. 1998, 1999, 2000, 2001, 2002 - All Rights Reserved
 *
 */

#ifndef __OPENTYPELAYOUTENGINE_H
#define __OPENTYPELAYOUTENGINE_H

#include "LETypes.h"
#include "LEGlyphFilter.h"
#include "LEFontInstance.h"
#include "LayoutEngine.h"

#include "GlyphSubstitutionTables.h"
#include "GlyphDefinitionTables.h"
#include "GlyphPositioningTables.h"

#include "cmemory.h"

U_NAMESPACE_BEGIN

/**
 * OpenTypeLayoutEngine implements complex text layout for OpenType fonts - that is
 * fonts which have GSUB and GPOS tables associated with them. In order to do this,
 * the glyph processsing step described for LayoutEngine is further broken into three
 * steps:
 *
 * 1) Character processing - this step analyses the characters and assigns a list of OpenType
 *    feature tags to each one. It may also change, remove or add characters, and change
 *    their order.
 *
 * 2) Glyph processing - This step performs character to glyph mapping,and uses the GSUB
 *    table associated with the font to perform glyph substitutions, such as ligature substitution.
 *
 * 3) Glyph post processing - in cases where the font doesn't directly contain a GSUB table,
 *    the previous two steps may have generated "fake" glyph indices to use with a "canned" GSUB
 *    table. This step turns those glyph indices into actual font-specific glyph indices, and may
 *    perform any other adjustments requried by the previous steps.
 *
 * OpenTypeLayoutEngine will also use the font's GPOS table to apply position adjustments
 * such as kerning and accent positioning.
 *
 * @see LayoutEngine
 *
 * @internal
 */
class OpenTypeLayoutEngine : public LayoutEngine
{
public:
    /**
     * This is the main constructor. It constructs an instance of OpenTypeLayoutEngine for
     * a particular font, script and language. It takes the GSUB table as a parameter since
     * LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has an
     * OpenType font.
     *
     * @param fontInstance - the font
     * @param scriptCode - the script
     * @param langaugeCode - the language
     * @param gsubTable - the GSUB table
     *
     * @see LayoutEngine::layoutEngineFactory
     * @see ScriptAndLangaugeTags.h for script and language codes
     *
     * @internal
     */
    OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
                            const GlyphSubstitutionTableHeader *gsubTable);

    /**
     * This constructor is used when the font requires a "canned" GSUB table which can't be known
     * until after this constructor has been invoked.
     *
     * @param fontInstance - the font
     * @param scriptCode - the script
     * @param langaugeCode - the language
     *
     * @internal
     */
    OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode);

    /**
     * The destructor, virtual for correct polymorphic invocation.
     *
     * @internal
     */
    virtual ~OpenTypeLayoutEngine();

    /**
     * A convenience method used to convert the script code into
     * the four byte script tag required by OpenType.
     *
     * @param scriptCode - the script code
     *
     * @return the four byte script tag
     *
     * @internal
     */
    static LETag getScriptTag(le_int32 scriptCode);

    /**
     * A convenience method used to convert the langauge code into
     * the four byte langauge tag required by OpenType.
     *
     * @param languageCode - the language code
     *
     * @return the four byte language tag
     *
     * @internal
     */
    static LETag getLangSysTag(le_int32 languageCode);

    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @draft ICU 2.2
     */
    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @draft ICU 2.2
     */
    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }

private:

    /**
     * This method is used by the constructors to convert the script
     * and language codes to four byte tags and save them.
     */
    void setScriptAndLanguageTags();

    /**
     * The array of script tags, indexed by script code.
     */
    static const LETag scriptTags[];

    /**
     * The address of this static class variable serves as this class's ID
     * for ICU "poor man's RTTI".
     */
    static const char fgClassID;

protected:
    /**
     * An array of pointers to four byte feature tags.
     * Each pointer points to a list of tags, terminated
     * by a special empty tag.
     *
     * @internal
     */
    const LETag **fFeatureTags;

    /**
     * A list of tags in the order in which the features in
     * the font should be applied, as opposed to using the
     * order of the lookups in the font.
     *
     * @internal
     */
    const LETag *fFeatureOrder;

    /**
     * The address of the GSUB table.
     *
     * @internal
     */
    const GlyphSubstitutionTableHeader *fGSUBTable;

    /**
     * The address of the GDEF table.
     *
     * @internal
     */
    const GlyphDefinitionTableHeader   *fGDEFTable;

    /**
     * The address of the GPOS table.
     *
     * @internal
     */
    const GlyphPositioningTableHeader  *fGPOSTable;

    /**
     * An optional filter used to inhibit substitutions
     * preformed by the GSUB table. This is used for some
     * "canned" GSUB tables to restrict substitutions to
     * glyphs that are in the font.
     *
     * @internal
     */
    LEGlyphFilter *fSubstitutionFilter;

    /**
     * The four byte script tag.
     *
     * @internal
     */
    LETag fScriptTag;

    /**
     * The four byte language tag
     *
     * @internal
     */
    LETag fLangSysTag;

    /**
     * This method does the OpenType character processing. It assigns the OpenType feature
     * tags to the characters, and may generate output characters that differ from the input
     * charcters dueto 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
     *
     * Output parameters:
     * @param outChars - the output character array, if different from the input
     * @param charIndices - the output character index array
     * @param featureTags - the output feature tag array
     * @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, le_int32 *&charIndices, const LETag **&featureTags, LEErrorCode &success) /*= 0;*/
    {
        if (LE_FAILURE(success)) {
            return 0;
        }

        if (offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
            success = LE_ILLEGAL_ARGUMENT_ERROR;
            return 0;
        }

        return count;
    };

    /**
     * This method does character to glyph mapping, and applies the GSUB table. The
     * default implementation calls mapCharsToGlyphs and then applies the GSUB table,
     * if there is one.
     *
     * Note that in the case of "canned" GSUB tables, the output glyph indices may be
     * "fake" glyph indices that need to be converted to "real" glyph indices by the
     * glyphPostProcessing 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 featureTags - the feature tag array
     *
     * Output parameters:
     * @param glyphs - the output glyph index array
     * @param charIndices - the output character index array
     * @param success - set to an error code if the operation fails
     *
     * @return the number of glyphs in the output glyph index array
     *
     * Note: if the character index array was already set by the characterProcessing
     * method, this method won't change it.
     *
     * @internal
     */
    virtual le_int32 glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
            const LETag **featureTags, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);

    /**
     * This method does any processing necessary to convert "fake"
     * glyph indices used by the glyphProcessing method into "real" glyph
     * indices which can be used to render the text. Note that in some
     * cases, such as CDAC Indic fonts, several "real" glyphs may be needed
     * to render one "fake" glyph.
     *
     * The default implementation of this method just returns the input glyph
     * index and character index arrays, assuming that no "fake" glyph indices
     * were needed to do GSUB processing.
     *
     * Input paramters:
     * @param tempGlyphs - the input "fake" glyph index array
     * @param tempCharIndices - the input "fake" character index array
     * @param tempGlyphCount - the number of "fake" glyph indices
     *
     * Output parameters:
     * @param glyphs - the output glyph index array
     * @param charIndices - the output character index array
     * @param success - set to an error code if the operation fails
     *
     * @return the number of glyph indices in the output glyph index array
     *
     * @internal
     */
    virtual le_int32 glyphPostProcessing(LEGlyphID tempGlyphs[], le_int32 tempCharIndices[], le_int32 tempGlyphCount,
                    LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success)
    {
        if (LE_FAILURE(success)) {
            return 0;
        }

        glyphs = tempGlyphs;
        charIndices = tempCharIndices;

        return tempGlyphCount;
    };

    /**
     * This method applies the characterProcessing, glyphProcessing and glyphPostProcessing
     * methods. Most subclasses will not need to 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 text is in a right to left directional run
     *
     * Output parameters:
     * @param glyphs - the glyph index array
     * @param charIndices - the character index array
     * @param success - set to an error code if the operation fails
     *
     * @return the number of glyphs in the glyph index array
     *
     * @see LayoutEngine::computeGlyphs
     *
     * @internal
     */
    virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphID *&glyphs, le_int32 *&charIndices, LEErrorCode &success);

    /**
     * This method uses the GPOS table, if there is one, to adjust the glyph positions.
     *
     * Input parameters:
     * @param glyphs - the input glyph array
     * @param glyphCount - the number of glyphs in the glyph array
     * @param x - the starting X position
     * @param y - the starting Y position
     *
     * Output parameters:
     * @param positions - the output X and Y positions (two entries per glyph)
     * @param success - 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, LEGlyphID glyphs[], le_int32 glyphCount, float positions[], LEErrorCode &success);

    /**
     * This method frees the feature tag array so that the
     * OpenTypeLayoutEngine can be reused for different text.
     * It is also called from our destructor.
     *
     * @internal
     */
    virtual void reset();
};

U_NAMESPACE_END
#endif

