/*
*
* (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
*
*/
#ifndef __GLYPHPOSITIONADJUSTMENTS_H
#define __GLYPHPOSITIONADJUSTMENTS_H
/**
* \file
* \internal
*/
#include "LETypes.h"
#include "OpenTypeTables.h"
U_NAMESPACE_BEGIN
class LEGlyphStorage;
class LEFontInstance;
class GlyphPositionAdjustments : public UMemory
{
private:
class Adjustment : public UMemory {
public:
inline Adjustment();
inline Adjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff = -1);
inline ~Adjustment();
inline float getXPlacement() const;
inline float getYPlacement() const;
inline float getXAdvance() const;
inline float getYAdvance() const;
inline le_int32 getBaseOffset() const;
inline void setXPlacement(float newXPlacement);
inline void setYPlacement(float newYPlacement);
inline void setXAdvance(float newXAdvance);
inline void setYAdvance(float newYAdvance);
inline void setBaseOffset(le_int32 newBaseOffset);
inline void adjustXPlacement(float xAdjustment);
inline void adjustYPlacement(float yAdjustment);
inline void adjustXAdvance(float xAdjustment);
inline void adjustYAdvance(float yAdjustment);
private:
float xPlacement;
float yPlacement;
float xAdvance;
float yAdvance;
le_int32 baseOffset;
// allow copying of this class because all of its fields are simple types
};
class EntryExitPoint : public UMemory
{
public:
inline EntryExitPoint();
inline ~EntryExitPoint();
inline le_bool isCursiveGlyph() const;
inline le_bool baselineIsLogicalEnd() const;
LEPoint *getEntryPoint(LEPoint &entryPoint) const;
LEPoint *getExitPoint(LEPoint &exitPoint) const;
inline void clearEntryPoint();
inline void clearExitPoint();
inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
inline void setCursiveGlyph(le_bool baselineIsLogicalEnd);
private:
enum EntryExitFlags
{
EEF_HAS_ENTRY_POINT = 0x80000000L,
EEF_HAS_EXIT_POINT = 0x40000000L,
EEF_IS_CURSIVE_GLYPH = 0x20000000L,
EEF_BASELINE_IS_LOGICAL_END = 0x10000000L
};
le_uint32 fFlags;
LEPoint fEntryPoint;
LEPoint fExitPoint;
};
le_int32 fGlyphCount;
EntryExitPoint *fEntryExitPoints;
Adjustment *fAdjustments;
GlyphPositionAdjustments();
public:
GlyphPositionAdjustments(le_int32 glyphCount);
~GlyphPositionAdjustments();
inline le_bool hasCursiveGlyphs() const;
inline le_bool isCursiveGlyph(le_int32 index) const;
inline le_bool baselineIsLogicalEnd(le_int32 index) const;
const LEPoint *getEntryPoint(le_int32 index, LEPoint &entryPoint) const;
const LEPoint *getExitPoint(le_int32 index, LEPoint &exitPoint) const;
inline float getXPlacement(le_int32 index) const;
inline float getYPlacement(le_int32 index) const;
inline float getXAdvance(le_int32 index) const;
inline float getYAdvance(le_int32 index) const;
inline le_int32 getBaseOffset(le_int32 index) const;
inline void setXPlacement(le_int32 index, float newXPlacement);
inline void setYPlacement(le_int32 index, float newYPlacement);
inline void setXAdvance(le_int32 index, float newXAdvance);
inline void setYAdvance(le_int32 index, float newYAdvance);
inline void setBaseOffset(le_int32 index, le_int32 newBaseOffset);
inline void adjustXPlacement(le_int32 index, float xAdjustment);
inline void adjustYPlacement(le_int32 index, float yAdjustment);
inline void adjustXAdvance(le_int32 index, float xAdjustment);
inline void adjustYAdvance(le_int32 index, float yAdjustment);
void clearEntryPoint(le_int32 index);
void clearExitPoint(le_int32 index);
void setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
void setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd);
void applyCursiveAdjustments(LEGlyphStorage &glyphStorage, le_bool rightToLeft, const LEFontInstance *fontInstance);
};
inline GlyphPositionAdjustments::Adjustment::Adjustment()
: xPlacement(0), yPlacement(0), xAdvance(0), yAdvance(0), baseOffset(-1)
{
// nothing else to do!
}
inline GlyphPositionAdjustments::Adjustment::Adjustment(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 GlyphPositionAdjustments::Adjustment::~Adjustment()
{
// nothing to do!
}
inline float GlyphPositionAdjustments::Adjustment::getXPlacement() const
{
return xPlacement;
}
inline float GlyphPositionAdjustments::Adjustment::getYPlacement() const
{
return yPlacement;
}
inline float GlyphPositionAdjustments::Adjustment::getXAdvance() const
{
return xAdvance;
}
inline float GlyphPositionAdjustments::Adjustment::getYAdvance() const
{
return yAdvance;
}
inline le_int32 GlyphPositionAdjustments::Adjustment::getBaseOffset() const
{
return baseOffset;
}
inline void GlyphPositionAdjustments::Adjustment::setXPlacement(float newXPlacement)
{
xPlacement = newXPlacement;
}
inline void GlyphPositionAdjustments::Adjustment::setYPlacement(float newYPlacement)
{
yPlacement = newYPlacement;
}
inline void GlyphPositionAdjustments::Adjustment::setXAdvance(float newXAdvance)
{
xAdvance = newXAdvance;
}
inline void GlyphPositionAdjustments::Adjustment::setYAdvance(float newYAdvance)
{
yAdvance = newYAdvance;
}
inline void GlyphPositionAdjustments::Adjustment::setBaseOffset(le_int32 newBaseOffset)
{
baseOffset = newBaseOffset;
}
inline void GlyphPositionAdjustments::Adjustment::adjustXPlacement(float xAdjustment)
{
xPlacement += xAdjustment;
}
inline void GlyphPositionAdjustments::Adjustment::adjustYPlacement(float yAdjustment)
{
yPlacement += yAdjustment;
}
inline void GlyphPositionAdjustments::Adjustment::adjustXAdvance(float xAdjustment)
{
xAdvance += xAdjustment;
}
inline void GlyphPositionAdjustments::Adjustment::adjustYAdvance(float yAdjustment)
{
yAdvance += yAdjustment;
}
inline GlyphPositionAdjustments::EntryExitPoint::EntryExitPoint()
: fFlags(0)
{
fEntryPoint.fX = fEntryPoint.fY = fExitPoint.fX = fExitPoint.fY = 0;
}
inline GlyphPositionAdjustments::EntryExitPoint::~EntryExitPoint()
{
// nothing special to do
}
inline le_bool GlyphPositionAdjustments::EntryExitPoint::isCursiveGlyph() const
{
return (fFlags & EEF_IS_CURSIVE_GLYPH) != 0;
}
inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd() const
{
return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
}
inline void GlyphPositionAdjustments::EntryExitPoint::clearEntryPoint()
{
fFlags &= ~EEF_HAS_ENTRY_POINT;
}
inline void GlyphPositionAdjustments::EntryExitPoint::clearExitPoint()
{
fFlags &= ~EEF_HAS_EXIT_POINT;
}
inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
{
if (baselineIsLogicalEnd) {
fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
} else {
fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH);
}
fEntryPoint = newEntryPoint;
}
inline void GlyphPositionAdjustments::EntryExitPoint::setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd)
{
if (baselineIsLogicalEnd) {
fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
} else {
fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH);
}
fExitPoint = newExitPoint;
}
inline void GlyphPositionAdjustments::EntryExitPoint::setCursiveGlyph(le_bool baselineIsLogicalEnd)
{
if (baselineIsLogicalEnd) {
fFlags |= (EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
} else {
fFlags |= EEF_IS_CURSIVE_GLYPH;
}
}
inline le_bool GlyphPositionAdjustments::isCursiveGlyph(le_int32 index) const
{
return fEntryExitPoints != NULL && fEntryExitPoints[index].isCursiveGlyph();
}
inline le_bool GlyphPositionAdjustments::baselineIsLogicalEnd(le_int32 index) const
{
return fEntryExitPoints != NULL && fEntryExitPoints[index].baselineIsLogicalEnd();
}
inline float GlyphPositionAdjustments::getXPlacement(le_int32 index) const
{
return fAdjustments[index].getXPlacement();
}
inline float GlyphPositionAdjustments::getYPlacement(le_int32 index) const
{
return fAdjustments[index].getYPlacement();
}
inline float GlyphPositionAdjustments::getXAdvance(le_int32 index) const
{
return fAdjustments[index].getXAdvance();
}
inline float GlyphPositionAdjustments::getYAdvance(le_int32 index) const
{
return fAdjustments[index].getYAdvance();
}
inline le_int32 GlyphPositionAdjustments::getBaseOffset(le_int32 index) const
{
return fAdjustments[index].getBaseOffset();
}
inline void GlyphPositionAdjustments::setXPlacement(le_int32 index, float newXPlacement)
{
fAdjustments[index].setXPlacement(newXPlacement);
}
inline void GlyphPositionAdjustments::setYPlacement(le_int32 index, float newYPlacement)
{
fAdjustments[index].setYPlacement(newYPlacement);
}
inline void GlyphPositionAdjustments::setXAdvance(le_int32 index, float newXAdvance)
{
fAdjustments[index].setXAdvance(newXAdvance);
}
inline void GlyphPositionAdjustments::setYAdvance(le_int32 index, float newYAdvance)
{
fAdjustments[index].setYAdvance(newYAdvance);
}
inline void GlyphPositionAdjustments::setBaseOffset(le_int32 index, le_int32 newBaseOffset)
{
fAdjustments[index].setBaseOffset(newBaseOffset);
}
inline void GlyphPositionAdjustments::adjustXPlacement(le_int32 index, float xAdjustment)
{
fAdjustments[index].adjustXPlacement(xAdjustment);
}
inline void GlyphPositionAdjustments::adjustYPlacement(le_int32 index, float yAdjustment)
{
fAdjustments[index].adjustYPlacement(yAdjustment);
}
inline void GlyphPositionAdjustments::adjustXAdvance(le_int32 index, float xAdjustment)
{
fAdjustments[index].adjustXAdvance(xAdjustment);
}
inline void GlyphPositionAdjustments::adjustYAdvance(le_int32 index, float yAdjustment)
{
fAdjustments[index].adjustYAdvance(yAdjustment);
}
inline le_bool GlyphPositionAdjustments::hasCursiveGlyphs() const
{
return fEntryExitPoints != NULL;
}
U_NAMESPACE_END
#endif