/*
 * @(#)GlyphPositionAdjustments.h	1.8 00/03/15
 *
 * (C) Copyright IBM Corp. 1998, 1999, 2000 - All Rights Reserved
 *
 */

#ifndef __GLYPHPOSITIONADJUSTMENTS_H
#define __GLYPHPOSITIONADJUSTMENTS_H

#include "LETypes.h"
#include "OpenTypeTables.h"

U_NAMESPACE_BEGIN

class GlyphPositionAdjustment : public UObject {
public:

    GlyphPositionAdjustment();
    GlyphPositionAdjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff = -1);
    ~GlyphPositionAdjustment();

    float    getXPlacement();
    float    getYPlacement();
    float    getXAdvance();
    float    getYAdvance();

    le_int32 getBaseOffset();

    void     setXPlacement(float newXPlacement);
    void     setYPlacement(float newYPlacement);
    void     setXAdvance(float newXAdvance);
    void     setYAdvance(float newYAdvance);

    void     setBaseOffset(le_int32 newBaseOffset);

    void    adjustXPlacement(float xAdjustment);
    void    adjustYPlacement(float yAdjustment);
    void    adjustXAdvance(float xAdjustment);
    void    adjustYAdvance(float yAdjustment);

    /**
     * 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:
    float xPlacement;
    float yPlacement;
    float xAdvance;
    float yAdvance;

    le_int32 baseOffset;

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

inline GlyphPositionAdjustment::GlyphPositionAdjustment()
  : xPlacement(0), yPlacement(0), xAdvance(0), yAdvance(0), baseOffset(-1)
{
    // nothing else to do!
}

inline GlyphPositionAdjustment::GlyphPositionAdjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff)
  : xPlacement(xPlace), yPlacement(yPlace), xAdvance(xAdv), yAdvance(yAdv), baseOffset(baseOff)
{
    // nothing else to do!
}

inline GlyphPositionAdjustment::~GlyphPositionAdjustment()
{
    // nothing to do!
}

inline float GlyphPositionAdjustment::getXPlacement()
{
    return xPlacement;
}

inline float GlyphPositionAdjustment::getYPlacement()
{
    return yPlacement;
}

inline float GlyphPositionAdjustment::getXAdvance()
{
    return xAdvance;
}

inline float GlyphPositionAdjustment::getYAdvance()
{
    return yAdvance;
}

inline le_int32 GlyphPositionAdjustment::getBaseOffset()
{
    return baseOffset;
}

inline void GlyphPositionAdjustment::setXPlacement(float newXPlacement)
{
    xPlacement = newXPlacement;
}

inline void GlyphPositionAdjustment::setYPlacement(float newYPlacement)
{
    yPlacement = newYPlacement;
}

inline void GlyphPositionAdjustment::setXAdvance(float newXAdvance)
{
    xAdvance = newXAdvance;
}

inline void GlyphPositionAdjustment::setYAdvance(float newYAdvance)
{
    yAdvance = newYAdvance;
}

inline void GlyphPositionAdjustment::setBaseOffset(le_int32 newBaseOffset)
{
    baseOffset = newBaseOffset;
}

inline void GlyphPositionAdjustment::adjustXPlacement(float xAdjustment)
{
    xPlacement += xAdjustment;
}

inline void GlyphPositionAdjustment::adjustYPlacement(float yAdjustment)
{
    yPlacement += yAdjustment;
}

inline void GlyphPositionAdjustment::adjustXAdvance(float xAdjustment)
{
    xAdvance += xAdjustment;
}

inline void GlyphPositionAdjustment::adjustYAdvance(float yAdjustment)
{
    yAdvance += yAdjustment;
}

U_NAMESPACE_END
#endif
