
/*
 * %W% %E%
 *
 * (C) Copyright IBM Corp. 1998-2003 - 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"

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 array of language tags, indexed by language code.
     */
    static const LETag languageTags[];

    /**
     * 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

