initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
This commit is contained in:
43
thirdparty/graphite/src/inc/CharInfo.h
vendored
Normal file
43
thirdparty/graphite/src/inc/CharInfo.h
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include "inc/Main.h"
|
||||
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class CharInfo
|
||||
{
|
||||
|
||||
public:
|
||||
CharInfo() : m_char(0), m_before(-1), m_after(-1), m_base(0), m_featureid(0), m_break(0), m_flags(0) {}
|
||||
void init(int cid) { m_char = cid; }
|
||||
unsigned int unicodeChar() const { return m_char; }
|
||||
void feats(int offset) { m_featureid = offset; }
|
||||
int fid() const { return m_featureid; }
|
||||
int breakWeight() const { return m_break; }
|
||||
void breakWeight(int val) { m_break = val; }
|
||||
int after() const { return m_after; }
|
||||
void after(int val) { m_after = val; }
|
||||
int before() const { return m_before; }
|
||||
void before(int val) { m_before = val; }
|
||||
size_t base() const { return m_base; }
|
||||
void base(size_t offset) { m_base = offset; }
|
||||
void addflags(uint8 val) { m_flags |= val; }
|
||||
uint8 flags() const { return m_flags; }
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
int m_char; // Unicode character from character stream
|
||||
int m_before; // slot index before us, comes before
|
||||
int m_after; // slot index after us, comes after
|
||||
size_t m_base; // offset into input string corresponding to this charinfo
|
||||
uint8 m_featureid; // index into features list in the segment
|
||||
int8 m_break; // breakweight coming from lb table
|
||||
uint8 m_flags; // 0,1 segment split.
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
struct gr_char_info : public graphite2::CharInfo {};
|
59
thirdparty/graphite/src/inc/CmapCache.h
vendored
Normal file
59
thirdparty/graphite/src/inc/CmapCache.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Face.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Face;
|
||||
|
||||
class Cmap
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~Cmap() throw() {}
|
||||
|
||||
virtual uint16 operator [] (const uint32) const throw() { return 0; }
|
||||
|
||||
virtual operator bool () const throw() { return false; }
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
};
|
||||
|
||||
class DirectCmap : public Cmap
|
||||
{
|
||||
DirectCmap(const DirectCmap &);
|
||||
DirectCmap & operator = (const DirectCmap &);
|
||||
|
||||
public:
|
||||
DirectCmap(const Face &);
|
||||
virtual uint16 operator [] (const uint32 usv) const throw();
|
||||
virtual operator bool () const throw();
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
const Face::Table _cmap;
|
||||
const void * _smp,
|
||||
* _bmp;
|
||||
};
|
||||
|
||||
class CachedCmap : public Cmap
|
||||
{
|
||||
CachedCmap(const CachedCmap &);
|
||||
CachedCmap & operator = (const CachedCmap &);
|
||||
|
||||
public:
|
||||
CachedCmap(const Face &);
|
||||
virtual ~CachedCmap() throw();
|
||||
virtual uint16 operator [] (const uint32 usv) const throw();
|
||||
virtual operator bool () const throw();
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
bool m_isBmpOnly;
|
||||
uint16 ** m_blocks;
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
148
thirdparty/graphite/src/inc/Code.h
vendored
Normal file
148
thirdparty/graphite/src/inc/Code.h
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
// This class represents loaded graphite stack machine code. It performs
|
||||
// basic sanity checks, on the incoming code to prevent more obvious problems
|
||||
// from crashing graphite.
|
||||
// Author: Tim Eves
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <graphite2/Types.h>
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Machine.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Silf;
|
||||
class Face;
|
||||
|
||||
enum passtype {
|
||||
PASS_TYPE_UNKNOWN = 0,
|
||||
PASS_TYPE_LINEBREAK,
|
||||
PASS_TYPE_SUBSTITUTE,
|
||||
PASS_TYPE_POSITIONING,
|
||||
PASS_TYPE_JUSTIFICATION
|
||||
};
|
||||
|
||||
namespace vm {
|
||||
|
||||
class Machine::Code
|
||||
{
|
||||
public:
|
||||
enum status_t
|
||||
{
|
||||
loaded,
|
||||
alloc_failed,
|
||||
invalid_opcode,
|
||||
unimplemented_opcode_used,
|
||||
out_of_range_data,
|
||||
jump_past_end,
|
||||
arguments_exhausted,
|
||||
missing_return,
|
||||
nested_context_item,
|
||||
underfull_stack
|
||||
};
|
||||
|
||||
private:
|
||||
class decoder;
|
||||
|
||||
instr * _code;
|
||||
byte * _data;
|
||||
size_t _data_size,
|
||||
_instr_count;
|
||||
byte _max_ref;
|
||||
mutable status_t _status;
|
||||
bool _constraint,
|
||||
_modify,
|
||||
_delete;
|
||||
mutable bool _own;
|
||||
|
||||
void release_buffers() throw ();
|
||||
void failure(const status_t) throw();
|
||||
|
||||
public:
|
||||
static size_t estimateCodeDataOut(size_t num_bytecodes, int nRules, int nSlots);
|
||||
|
||||
Code() throw();
|
||||
Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
|
||||
uint8 pre_context, uint16 rule_length, const Silf &, const Face &,
|
||||
enum passtype pt, byte * * const _out = 0);
|
||||
Code(const Machine::Code &) throw();
|
||||
~Code() throw();
|
||||
|
||||
Code & operator=(const Code &rhs) throw();
|
||||
operator bool () const throw() { return _code && status() == loaded; }
|
||||
status_t status() const throw() { return _status; }
|
||||
bool constraint() const throw() { return _constraint; }
|
||||
size_t dataSize() const throw() { return _data_size; }
|
||||
size_t instructionCount() const throw() { return _instr_count; }
|
||||
bool immutable() const throw() { return !(_delete || _modify); }
|
||||
bool deletes() const throw() { return _delete; }
|
||||
size_t maxRef() const throw() { return _max_ref; }
|
||||
void externalProgramMoved(ptrdiff_t) throw();
|
||||
|
||||
int32 run(Machine &m, slotref * & map) const;
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
};
|
||||
|
||||
inline
|
||||
size_t Machine::Code::estimateCodeDataOut(size_t n_bc, int nRules, int nSlots)
|
||||
{
|
||||
// max is: all codes are instructions + 1 for each rule + max tempcopies
|
||||
// allocate space for separate maximal code and data then merge them later
|
||||
return (n_bc + nRules + nSlots) * sizeof(instr) + n_bc * sizeof(byte);
|
||||
}
|
||||
|
||||
|
||||
inline Machine::Code::Code() throw()
|
||||
: _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0),
|
||||
_status(loaded), _constraint(false), _modify(false), _delete(false),
|
||||
_own(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline Machine::Code::Code(const Machine::Code &obj) throw ()
|
||||
: _code(obj._code),
|
||||
_data(obj._data),
|
||||
_data_size(obj._data_size),
|
||||
_instr_count(obj._instr_count),
|
||||
_max_ref(obj._max_ref),
|
||||
_status(obj._status),
|
||||
_constraint(obj._constraint),
|
||||
_modify(obj._modify),
|
||||
_delete(obj._delete),
|
||||
_own(obj._own)
|
||||
{
|
||||
obj._own = false;
|
||||
}
|
||||
|
||||
inline Machine::Code & Machine::Code::operator=(const Machine::Code &rhs) throw() {
|
||||
if (_instr_count > 0)
|
||||
release_buffers();
|
||||
_code = rhs._code;
|
||||
_data = rhs._data;
|
||||
_data_size = rhs._data_size;
|
||||
_instr_count = rhs._instr_count;
|
||||
_status = rhs._status;
|
||||
_constraint = rhs._constraint;
|
||||
_modify = rhs._modify;
|
||||
_delete = rhs._delete;
|
||||
_own = rhs._own;
|
||||
rhs._own = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void Machine::Code::externalProgramMoved(ptrdiff_t dist) throw()
|
||||
{
|
||||
if (_code && !_own)
|
||||
{
|
||||
_code += dist / signed(sizeof(instr));
|
||||
_data += dist;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
} // namespace graphite2
|
222
thirdparty/graphite/src/inc/Collider.h
vendored
Normal file
222
thirdparty/graphite/src/inc/Collider.h
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "inc/List.h"
|
||||
#include "inc/Position.h"
|
||||
#include "inc/Intervals.h"
|
||||
#include "inc/debug.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class json;
|
||||
class Slot;
|
||||
class Segment;
|
||||
|
||||
#define SLOTCOLSETUINTPROP(x, y) uint16 x() const { return _ ##x; } void y (uint16 v) { _ ##x = v; }
|
||||
#define SLOTCOLSETINTPROP(x, y) int16 x() const { return _ ##x; } void y (int16 v) { _ ##x = v; }
|
||||
#define SLOTCOLSETPOSITIONPROP(x, y) const Position &x() const { return _ ##x; } void y (const Position &v) { _ ##x = v; }
|
||||
|
||||
// Slot attributes related to collision-fixing
|
||||
class SlotCollision
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
// COLL_TESTONLY = 0, // default - test other glyphs for collision with this one, but don't move this one
|
||||
COLL_FIX = 1, // fix collisions involving this glyph
|
||||
COLL_IGNORE = 2, // ignore this glyph altogether
|
||||
COLL_START = 4, // start of range of possible collisions
|
||||
COLL_END = 8, // end of range of possible collisions
|
||||
COLL_KERN = 16, // collisions with this glyph are fixed by adding kerning space after it
|
||||
COLL_ISCOL = 32, // this glyph has a collision
|
||||
COLL_KNOWN = 64, // we've figured out what's happening with this glyph
|
||||
COLL_ISSPACE = 128, // treat this glyph as a space with regard to kerning
|
||||
COLL_TEMPLOCK = 256, // Lock glyphs that have been given priority positioning
|
||||
////COLL_JUMPABLE = 128, // moving glyphs may jump this stationary glyph in any direction - DELETE
|
||||
////COLL_OVERLAP = 256, // use maxoverlap to restrict - DELETE
|
||||
};
|
||||
|
||||
// Behavior for the collision.order attribute. To GDL this is an enum, to us it's a bitfield, with only 1 bit set
|
||||
// Allows for easier inversion.
|
||||
enum {
|
||||
SEQ_ORDER_LEFTDOWN = 1,
|
||||
SEQ_ORDER_RIGHTUP = 2,
|
||||
SEQ_ORDER_NOABOVE = 4,
|
||||
SEQ_ORDER_NOBELOW = 8,
|
||||
SEQ_ORDER_NOLEFT = 16,
|
||||
SEQ_ORDER_NORIGHT = 32
|
||||
};
|
||||
|
||||
SlotCollision(Segment *seg, Slot *slot);
|
||||
void initFromSlot(Segment *seg, Slot *slot);
|
||||
|
||||
const Rect &limit() const { return _limit; }
|
||||
void setLimit(const Rect &r) { _limit = r; }
|
||||
SLOTCOLSETPOSITIONPROP(shift, setShift)
|
||||
SLOTCOLSETPOSITIONPROP(offset, setOffset)
|
||||
SLOTCOLSETPOSITIONPROP(exclOffset, setExclOffset)
|
||||
SLOTCOLSETUINTPROP(margin, setMargin)
|
||||
SLOTCOLSETUINTPROP(marginWt, setMarginWt)
|
||||
SLOTCOLSETUINTPROP(flags, setFlags)
|
||||
SLOTCOLSETUINTPROP(exclGlyph, setExclGlyph)
|
||||
SLOTCOLSETUINTPROP(seqClass, setSeqClass)
|
||||
SLOTCOLSETUINTPROP(seqProxClass, setSeqProxClass)
|
||||
SLOTCOLSETUINTPROP(seqOrder, setSeqOrder)
|
||||
SLOTCOLSETINTPROP(seqAboveXoff, setSeqAboveXoff)
|
||||
SLOTCOLSETUINTPROP(seqAboveWt, setSeqAboveWt)
|
||||
SLOTCOLSETINTPROP(seqBelowXlim, setSeqBelowXlim)
|
||||
SLOTCOLSETUINTPROP(seqBelowWt, setSeqBelowWt)
|
||||
SLOTCOLSETUINTPROP(seqValignHt, setSeqValignHt)
|
||||
SLOTCOLSETUINTPROP(seqValignWt, setSeqValignWt)
|
||||
|
||||
float getKern(int dir) const;
|
||||
bool ignore() const;
|
||||
|
||||
private:
|
||||
Rect _limit;
|
||||
Position _shift; // adjustment within the given pass
|
||||
Position _offset; // total adjustment for collisions
|
||||
Position _exclOffset;
|
||||
uint16 _margin;
|
||||
uint16 _marginWt;
|
||||
uint16 _flags;
|
||||
uint16 _exclGlyph;
|
||||
uint16 _seqClass;
|
||||
uint16 _seqProxClass;
|
||||
uint16 _seqOrder;
|
||||
int16 _seqAboveXoff;
|
||||
uint16 _seqAboveWt;
|
||||
int16 _seqBelowXlim;
|
||||
uint16 _seqBelowWt;
|
||||
uint16 _seqValignHt;
|
||||
uint16 _seqValignWt;
|
||||
|
||||
}; // end of class SlotColllision
|
||||
|
||||
struct BBox;
|
||||
struct SlantBox;
|
||||
|
||||
class ShiftCollider
|
||||
{
|
||||
public:
|
||||
typedef std::pair<float, float> fpair;
|
||||
typedef Vector<fpair> vfpairs;
|
||||
typedef vfpairs::iterator ivfpairs;
|
||||
|
||||
ShiftCollider(json *dbgout);
|
||||
~ShiftCollider() throw() { };
|
||||
|
||||
bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint,
|
||||
float margin, float marginMin, const Position &currShift,
|
||||
const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout);
|
||||
bool mergeSlot(Segment *seg, Slot *slot, const SlotCollision *cinfo, const Position &currShift, bool isAfter,
|
||||
bool sameCluster, bool &hasCol, bool isExclusion, GR_MAYBE_UNUSED json * const dbgout);
|
||||
Position resolve(Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout);
|
||||
void addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int mode);
|
||||
void removeBox(const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, int mode);
|
||||
const Position &origin() const { return _origin; }
|
||||
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
void outputJsonDbg(json * const dbgout, Segment *seg, int axis);
|
||||
void outputJsonDbgStartSlot(json * const dbgout, Segment *seg);
|
||||
void outputJsonDbgEndSlot(json * const dbgout, Position resultPos, int bestAxis, bool isCol);
|
||||
void outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis, float tleft, float bestCost, float bestVal);
|
||||
void outputJsonDbgRawRanges(json * const dbgout, int axis);
|
||||
void outputJsonDbgRemovals(json * const dbgout, int axis, Segment *seg);
|
||||
#endif
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
protected:
|
||||
Zones _ranges[4]; // possible movements in 4 directions (horizontally, vertically, diagonally);
|
||||
Slot * _target; // the glyph to fix
|
||||
Rect _limit;
|
||||
Position _currShift;
|
||||
Position _currOffset;
|
||||
Position _origin; // Base for all relative calculations
|
||||
float _margin;
|
||||
float _marginWt;
|
||||
float _len[4];
|
||||
uint16 _seqClass;
|
||||
uint16 _seqProxClass;
|
||||
uint16 _seqOrder;
|
||||
|
||||
//bool _scraping[4];
|
||||
|
||||
}; // end of class ShiftCollider
|
||||
|
||||
inline
|
||||
ShiftCollider::ShiftCollider(GR_MAYBE_UNUSED json *dbgout)
|
||||
: _target(0),
|
||||
_margin(0.0),
|
||||
_marginWt(0.0),
|
||||
_seqClass(0),
|
||||
_seqProxClass(0),
|
||||
_seqOrder(0)
|
||||
{
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
for (int i = 0; i < 4; ++i)
|
||||
_ranges[i].setdebug(dbgout);
|
||||
#endif
|
||||
}
|
||||
|
||||
class KernCollider
|
||||
{
|
||||
public:
|
||||
KernCollider(json *dbg);
|
||||
~KernCollider() throw() { };
|
||||
bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint, float margin,
|
||||
const Position &currShift, const Position &offsetPrev, int dir,
|
||||
float ymin, float ymax, json * const dbgout);
|
||||
bool mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, json * const dbgout);
|
||||
Position resolve(Segment *seg, Slot *slot, int dir, json * const dbgout);
|
||||
void shift(const Position &mv, int dir);
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
private:
|
||||
Slot * _target; // the glyph to fix
|
||||
Rect _limit;
|
||||
float _margin;
|
||||
Position _offsetPrev; // kern from a previous pass
|
||||
Position _currShift; // NOT USED??
|
||||
float _miny; // y-coordinates offset by global slot position
|
||||
float _maxy;
|
||||
Vector<float> _edges; // edges of horizontal slices
|
||||
float _sliceWidth; // width of each slice
|
||||
float _mingap;
|
||||
float _xbound; // max or min edge
|
||||
bool _hit;
|
||||
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
// Debugging
|
||||
Segment * _seg;
|
||||
Vector<float> _nearEdges; // closest potential collision in each slice
|
||||
Vector<Slot*> _slotNear;
|
||||
#endif
|
||||
}; // end of class KernCollider
|
||||
|
||||
|
||||
inline
|
||||
float sqr(float x) {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
inline
|
||||
KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg)
|
||||
: _target(0),
|
||||
_margin(0.0f),
|
||||
_miny(-1e38f),
|
||||
_maxy(1e38f),
|
||||
_sliceWidth(0.0f),
|
||||
_mingap(0.0f),
|
||||
_xbound(0.0),
|
||||
_hit(false)
|
||||
{
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
_seg = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
}; // end of namespace graphite2
|
81
thirdparty/graphite/src/inc/Compression.h
vendored
Normal file
81
thirdparty/graphite/src/inc/Compression.h
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2015, SIL International, All rights reserved.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned __int8 u8;
|
||||
typedef unsigned __int16 u16;
|
||||
typedef unsigned __int32 u32;
|
||||
typedef unsigned __int64 u64;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
#endif
|
||||
|
||||
ptrdiff_t const MINMATCH = 4,
|
||||
LASTLITERALS = 5,
|
||||
MINCODA = LASTLITERALS+1,
|
||||
MINSRCSIZE = 13;
|
||||
|
||||
template<int S>
|
||||
inline
|
||||
void unaligned_copy(void * d, void const * s) {
|
||||
::memcpy(d, s, S);
|
||||
}
|
||||
|
||||
inline
|
||||
size_t align(size_t p) {
|
||||
return (p + sizeof(unsigned long)-1) & ~(sizeof(unsigned long)-1);
|
||||
}
|
||||
|
||||
inline
|
||||
u8 * safe_copy(u8 * d, u8 const * s, size_t n) {
|
||||
while (n--) *d++ = *s++;
|
||||
return d;
|
||||
}
|
||||
|
||||
inline
|
||||
u8 * overrun_copy(u8 * d, u8 const * s, size_t n) {
|
||||
size_t const WS = sizeof(unsigned long);
|
||||
u8 const * e = s + n;
|
||||
do
|
||||
{
|
||||
unaligned_copy<WS>(d, s);
|
||||
d += WS;
|
||||
s += WS;
|
||||
}
|
||||
while (s < e);
|
||||
d-=(s-e);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
u8 * fast_copy(u8 * d, u8 const * s, size_t n) {
|
||||
size_t const WS = sizeof(unsigned long);
|
||||
size_t wn = n/WS;
|
||||
while (wn--)
|
||||
{
|
||||
unaligned_copy<WS>(d, s);
|
||||
d += WS;
|
||||
s += WS;
|
||||
}
|
||||
n &= WS-1;
|
||||
return safe_copy(d, s, n);
|
||||
}
|
||||
|
||||
|
||||
} // end of anonymous namespace
|
31
thirdparty/graphite/src/inc/Decompressor.h
vendored
Normal file
31
thirdparty/graphite/src/inc/Decompressor.h
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2015, SIL International, All rights reserved.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace lz4
|
||||
{
|
||||
|
||||
// decompress an LZ4 block
|
||||
// Parameters:
|
||||
// @in - Input buffer containing an LZ4 block.
|
||||
// @in_size - Size of the input LZ4 block in bytes.
|
||||
// @out - Output buffer to hold decompressed results.
|
||||
// @out_size - The size of the buffer pointed to by @out.
|
||||
// Invariants:
|
||||
// @in - This buffer must be at least 1 machine word in length,
|
||||
// regardless of the actual LZ4 block size.
|
||||
// @in_size - This must be at least 4 and must also be <= to the
|
||||
// allocated buffer @in.
|
||||
// @out - This must be bigger than the input buffer and at least
|
||||
// 13 bytes.
|
||||
// @out_size - Must always be big enough to hold the expected size.
|
||||
// Return:
|
||||
// -1 - Decompression failed.
|
||||
// size - Actual number of bytes decompressed.
|
||||
int decompress(void const *in, size_t in_size, void *out, size_t out_size);
|
||||
|
||||
} // end of namespace shrinker
|
86
thirdparty/graphite/src/inc/Endian.h
vendored
Normal file
86
thirdparty/graphite/src/inc/Endian.h
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2011, SIL International, All rights reserved.
|
||||
/*
|
||||
Description:
|
||||
A set of fast template based decoders for decoding values of any C integer
|
||||
type up to long int size laid out with most significant byte first or least
|
||||
significant byte first (aka big endian or little endian). These are CPU
|
||||
byte order agnostic and will function the same regardless of the CPUs native
|
||||
byte order.
|
||||
|
||||
Being template based means if the either le or be class is not used then
|
||||
template code of unused functions will not be instantiated by the compiler
|
||||
and thus shouldn't cause any overhead.
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class be
|
||||
{
|
||||
template<int S>
|
||||
inline static unsigned long int _peek(const unsigned char * p) {
|
||||
return _peek<S/2>(p) << (S/2)*8 | _peek<S/2>(p+S/2);
|
||||
}
|
||||
public:
|
||||
template<typename T>
|
||||
inline static T peek(const void * p) {
|
||||
return T(_peek<sizeof(T)>(static_cast<const unsigned char *>(p)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static T read(const unsigned char * &p) {
|
||||
const T r = T(_peek<sizeof(T)>(p));
|
||||
p += sizeof r;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static T swap(const T x) {
|
||||
return T(_peek<sizeof(T)>(reinterpret_cast<const unsigned char *>(&x)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static void skip(const unsigned char * &p, size_t n=1) {
|
||||
p += sizeof(T)*n;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline unsigned long int be::_peek<1>(const unsigned char * p) { return *p; }
|
||||
|
||||
|
||||
class le
|
||||
{
|
||||
template<int S>
|
||||
inline static unsigned long int _peek(const unsigned char * p) {
|
||||
return _peek<S/2>(p) | _peek<S/2>(p+S/2) << (S/2)*8;
|
||||
}
|
||||
public:
|
||||
template<typename T>
|
||||
inline static T peek(const void * p) {
|
||||
return T(_peek<sizeof(T)>(static_cast<const unsigned char *>(p)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static T read(const unsigned char * &p) {
|
||||
const T r = T(_peek<sizeof(T)>(p));
|
||||
p += sizeof r;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static T swap(const T x) {
|
||||
return T(_peek<sizeof(T)>(reinterpret_cast<const unsigned char *>(&x)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static void skip(const unsigned char * &p, size_t n=1) {
|
||||
p += sizeof(T)*n;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline unsigned long int le::_peek<1>(const unsigned char * p) { return *p; }
|
111
thirdparty/graphite/src/inc/Error.h
vendored
Normal file
111
thirdparty/graphite/src/inc/Error.h
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2013, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
// numbers are explicitly assigned for future proofing
|
||||
|
||||
namespace graphite2
|
||||
{
|
||||
|
||||
class Error
|
||||
{
|
||||
public:
|
||||
Error() : _e(0) {};
|
||||
operator bool() { return (_e != 0); }
|
||||
int error() { return _e; }
|
||||
void error(int e) { _e = e; }
|
||||
bool test(bool pr, int err) { return (_e = pr ? err : 0); }
|
||||
|
||||
private:
|
||||
int _e;
|
||||
};
|
||||
|
||||
enum errcontext {
|
||||
EC_READGLYPHS = 1, // while reading glyphs
|
||||
EC_READSILF = 2, // in Silf table
|
||||
EC_ASILF = 3, // in Silf %d
|
||||
EC_APASS = 4, // in Silf %d, pass %d
|
||||
EC_PASSCCODE = 5, // in pass constraint code for Silf %d, pass %d
|
||||
EC_ARULE = 6, // in Silf %d, pass %d, rule %d
|
||||
EC_ASTARTS = 7, // in Silf %d, pass %d, start state %d
|
||||
EC_ATRANS = 8, // in Silf %d, pass %d, fsm state %d
|
||||
EC_ARULEMAP = 9 // in Silf %d, pass %d, state %d
|
||||
};
|
||||
|
||||
enum error {
|
||||
E_OUTOFMEM = 1, // Out of memory
|
||||
E_NOGLYPHS = 2, // There are no glyphs in the font
|
||||
E_BADUPEM = 3, // The units per em for the font is bad (0)
|
||||
E_BADCMAP = 4, // The font does not contain any useful cmaps
|
||||
E_NOSILF = 5, // Missing Silf table
|
||||
E_TOOOLD = 6, // Silf table version is too old
|
||||
E_BADSIZE = 7, // context object has the wrong structural size
|
||||
// Silf Subtable Errors take a Silf subtable number * 256 in the context
|
||||
E_BADMAXGLYPH = 8, // Silf max glyph id is too high
|
||||
E_BADNUMJUSTS = 9, // Number of Silf justification blocks is too high
|
||||
E_BADENDJUSTS = 10, // Silf justification blocks take too much of the Silf table space
|
||||
E_BADCRITFEATURES = 11, // Critical features section in a Silf table is too big
|
||||
E_BADSCRIPTTAGS = 12, // Silf script tags area is too big
|
||||
E_BADAPSEUDO = 13, // The pseudo glyph attribute number is too high
|
||||
E_BADABREAK = 14, // The linebreak glyph attribute number is too high
|
||||
E_BADABIDI = 15, // The bidi glyph attribute number is too high
|
||||
E_BADAMIRROR = 16, // The mirrored glyph attribute number is too high
|
||||
E_BADNUMPASSES = 17, // The number of passes is > 128
|
||||
E_BADPASSESSTART = 18, // The Silf table is too small to hold any passes
|
||||
E_BADPASSBOUND = 19, // The positioning pass number is too low or the substitution pass number is too high
|
||||
E_BADPPASS = 20, // The positioning pass number is too high
|
||||
E_BADSPASS = 21, // the substitution pass number is too high
|
||||
E_BADJPASSBOUND = 22, // the justification pass must be higher than the positioning pass
|
||||
E_BADJPASS = 23, // the justification pass is too high
|
||||
E_BADALIG = 24, // the number of initial ligature component glyph attributes is too high
|
||||
E_BADBPASS = 25, // the bidi pass number is specified and is either too high or too low
|
||||
E_BADNUMPSEUDO = 26, // The number of pseudo glyphs is too high
|
||||
E_BADCLASSSIZE = 27, // The size of the classes block is bad
|
||||
E_TOOMANYLINEAR = 28, // The number of linear classes in the silf table is too high
|
||||
E_CLASSESTOOBIG = 29, // There are too many classes for the space allocated in the Silf subtable
|
||||
E_MISALIGNEDCLASSES = 30, // The class offsets in the class table don't line up with the number of classes
|
||||
E_HIGHCLASSOFFSET = 31, // The class offsets point out of the class table
|
||||
E_BADCLASSOFFSET = 32, // A class offset is less than one following it
|
||||
E_BADCLASSLOOKUPINFO = 33, // The search header info for a non-linear class has wrong values in it
|
||||
// Pass subtable errors. Context has pass number * 65536
|
||||
E_BADPASSSTART = 34, // The start offset for a particular pass is bad
|
||||
E_BADPASSEND = 35, // The end offset for a particular pass is bad
|
||||
E_BADPASSLENGTH = 36, // The length of the pass is too small
|
||||
E_BADNUMTRANS = 37, // The number of transition states in the fsm is bad
|
||||
E_BADNUMSUCCESS = 38, // The number of success states in the fsm is bad
|
||||
E_BADNUMSTATES = 39, // The number of states in the fsm is bad
|
||||
E_NORANGES = 40, // There are no columns in the fsm
|
||||
E_BADRULEMAPLEN = 41, // The size of the success state to rule mapping is bad
|
||||
E_BADCTXTLENBOUNDS = 42, // The precontext maximum is greater than its minimum
|
||||
E_BADCTXTLENS = 43, // The lists of rule lengths or pre context lengths is bad
|
||||
E_BADPASSCCODEPTR = 44, // The pass constraint code position does not align with where the forward reference says it should be
|
||||
E_BADRULECCODEPTR = 45, // The rule constraint code position does not align with where the forward reference says it should be
|
||||
E_BADCCODELEN = 46, // Bad rule/pass constraint code length
|
||||
E_BADACTIONCODEPTR = 47, // The action code position does not align with where the forward reference says it should be
|
||||
E_MUTABLECCODE = 48, // Constraint code edits slots. It shouldn't.
|
||||
E_BADSTATE = 49, // Bad state transition referencing an illegal state
|
||||
E_BADRULEMAPPING = 50, // The structure of the rule mapping is bad
|
||||
E_BADRANGE = 51, // Bad column range structure including a glyph in more than one column
|
||||
E_BADRULENUM = 52, // A reference to a rule is out of range (too high)
|
||||
E_BADACOLLISION = 53, // Bad Silf table collision attribute number (too high)
|
||||
E_BADEMPTYPASS = 54, // Can't have empty passes (no rules) except for collision passes
|
||||
E_BADSILFVERSION = 55, // The Silf table has a bad version (probably too high)
|
||||
E_BADCOLLISIONPASS = 56, // Collision flags set on a non positioning pass
|
||||
E_BADNUMCOLUMNS = 57, // Arbitrarily limit number of columns in fsm
|
||||
// Code errors
|
||||
E_CODEFAILURE = 60, // Base code error. The following subcodes must align with Machine::Code::status_t in Code.h
|
||||
E_CODEALLOC = 61, // Out of memory
|
||||
E_INVALIDOPCODE = 62, // Invalid op code
|
||||
E_UNIMPOPCODE = 63, // Unimplemented op code encountered
|
||||
E_OUTOFRANGECODE = 64, // Code argument out of range
|
||||
E_BADJUMPCODE = 65, // Code jumps past end of op codes
|
||||
E_CODEBADARGS = 66, // Code arguments exhausted
|
||||
E_CODENORETURN = 67, // Missing return type op code at end of code
|
||||
E_CODENESTEDCTXT = 68, // Nested context encountered in code
|
||||
// Compression errors
|
||||
E_BADSCHEME = 69,
|
||||
E_SHRINKERFAILED = 70,
|
||||
};
|
||||
|
||||
}
|
202
thirdparty/graphite/src/inc/Face.h
vendored
Normal file
202
thirdparty/graphite/src/inc/Face.h
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "graphite2/Font.h"
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/FeatureMap.h"
|
||||
#include "inc/TtfUtil.h"
|
||||
#include "inc/Silf.h"
|
||||
#include "inc/Error.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Cmap;
|
||||
class FileFace;
|
||||
class GlyphCache;
|
||||
class NameTable;
|
||||
class json;
|
||||
class Font;
|
||||
|
||||
|
||||
using TtfUtil::Tag;
|
||||
|
||||
// These are the actual tags, as distinct from the consecutive IDs in TtfUtil.h
|
||||
|
||||
class Face
|
||||
{
|
||||
// Prevent any kind of copying
|
||||
Face(const Face&);
|
||||
Face& operator=(const Face&);
|
||||
|
||||
public:
|
||||
class Table;
|
||||
static float default_glyph_advance(const void* face_ptr, gr_uint16 glyphid);
|
||||
|
||||
Face(const void* appFaceHandle/*non-NULL*/, const gr_face_ops & ops);
|
||||
virtual ~Face();
|
||||
|
||||
virtual bool runGraphite(Segment *seg, const Silf *silf) const;
|
||||
|
||||
public:
|
||||
bool readGlyphs(uint32 faceOptions);
|
||||
bool readGraphite(const Table & silf);
|
||||
bool readFeatures();
|
||||
void takeFileFace(FileFace* pFileFace/*takes ownership*/);
|
||||
|
||||
const SillMap & theSill() const;
|
||||
const GlyphCache & glyphs() const;
|
||||
Cmap & cmap() const;
|
||||
NameTable * nameTable() const;
|
||||
void setLogger(FILE *log_file);
|
||||
json * logger() const throw();
|
||||
|
||||
const Silf * chooseSilf(uint32 script) const;
|
||||
uint16 languageForLocale(const char * locale) const;
|
||||
|
||||
// Features
|
||||
uint16 numFeatures() const;
|
||||
const FeatureRef * featureById(uint32 id) const;
|
||||
const FeatureRef * feature(uint16 index) const;
|
||||
|
||||
// Glyph related
|
||||
int32 getGlyphMetric(uint16 gid, uint8 metric) const;
|
||||
uint16 findPseudo(uint32 uid) const;
|
||||
|
||||
// Errors
|
||||
unsigned int error() const { return m_error; }
|
||||
bool error(Error e) { m_error = e.error(); return false; }
|
||||
unsigned int error_context() const { return m_error; }
|
||||
void error_context(unsigned int errcntxt) { m_errcntxt = errcntxt; }
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
SillMap m_Sill;
|
||||
gr_face_ops m_ops;
|
||||
const void * m_appFaceHandle; // non-NULL
|
||||
FileFace * m_pFileFace; //owned
|
||||
mutable GlyphCache * m_pGlyphFaceCache; // owned - never NULL
|
||||
mutable Cmap * m_cmap; // cmap cache if available
|
||||
mutable NameTable * m_pNames;
|
||||
mutable json * m_logger;
|
||||
unsigned int m_error;
|
||||
unsigned int m_errcntxt;
|
||||
protected:
|
||||
Silf * m_silfs; // silf subtables.
|
||||
uint16 m_numSilf; // num silf subtables in the silf table
|
||||
private:
|
||||
uint16 m_ascent,
|
||||
m_descent;
|
||||
#ifdef GRAPHITE2_TELEMETRY
|
||||
public:
|
||||
mutable telemetry tele;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline
|
||||
const SillMap & Face::theSill() const
|
||||
{
|
||||
return m_Sill;
|
||||
}
|
||||
|
||||
inline
|
||||
uint16 Face::numFeatures() const
|
||||
{
|
||||
return m_Sill.theFeatureMap().numFeats();
|
||||
}
|
||||
|
||||
inline
|
||||
const FeatureRef * Face::featureById(uint32 id) const
|
||||
{
|
||||
return m_Sill.theFeatureMap().findFeatureRef(id);
|
||||
}
|
||||
|
||||
inline
|
||||
const FeatureRef *Face::feature(uint16 index) const
|
||||
{
|
||||
return m_Sill.theFeatureMap().feature(index);
|
||||
}
|
||||
|
||||
inline
|
||||
const GlyphCache & Face::glyphs() const
|
||||
{
|
||||
return *m_pGlyphFaceCache;
|
||||
}
|
||||
|
||||
inline
|
||||
Cmap & Face::cmap() const
|
||||
{
|
||||
return *m_cmap;
|
||||
};
|
||||
|
||||
inline
|
||||
json * Face::logger() const throw()
|
||||
{
|
||||
return m_logger;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Face::Table
|
||||
{
|
||||
const Face * _f;
|
||||
mutable const byte * _p;
|
||||
size_t _sz;
|
||||
bool _compressed;
|
||||
|
||||
Error decompress();
|
||||
|
||||
void release();
|
||||
|
||||
public:
|
||||
Table() throw();
|
||||
Table(const Face & face, const Tag n, uint32 version=0xffffffff) throw();
|
||||
~Table() throw();
|
||||
Table(const Table && rhs) throw();
|
||||
|
||||
operator const byte * () const throw();
|
||||
|
||||
size_t size() const throw();
|
||||
Table & operator = (const Table && rhs) throw();
|
||||
};
|
||||
|
||||
inline
|
||||
Face::Table::Table() throw()
|
||||
: _f(0), _p(0), _sz(0), _compressed(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Face::Table::Table(const Table && rhs) throw()
|
||||
: _f(rhs._f), _p(rhs._p), _sz(rhs._sz), _compressed(rhs._compressed)
|
||||
{
|
||||
rhs._p = 0;
|
||||
}
|
||||
|
||||
inline
|
||||
Face::Table::~Table() throw()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
inline
|
||||
Face::Table::operator const byte * () const throw()
|
||||
{
|
||||
return _p;
|
||||
}
|
||||
|
||||
inline
|
||||
size_t Face::Table::size() const throw()
|
||||
{
|
||||
return _sz;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
struct gr_face : public graphite2::Face {};
|
175
thirdparty/graphite/src/inc/FeatureMap.h
vendored
Normal file
175
thirdparty/graphite/src/inc/FeatureMap.h
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include "inc/Main.h"
|
||||
#include "inc/FeatureVal.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
// Forward declarations for implmentation types
|
||||
class FeatureMap;
|
||||
class Face;
|
||||
|
||||
|
||||
class FeatureSetting
|
||||
{
|
||||
public:
|
||||
FeatureSetting(int16 theValue, uint16 labelId) : m_label(labelId), m_value(theValue) {};
|
||||
uint16 label() const { return m_label; }
|
||||
int16 value() const { return m_value; }
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
FeatureSetting(const FeatureSetting & fs) : m_label(fs.m_label), m_value(fs.m_value) {};
|
||||
|
||||
uint16 m_label;
|
||||
int16 m_value;
|
||||
};
|
||||
|
||||
class FeatureRef
|
||||
{
|
||||
typedef uint32 chunk_t;
|
||||
static const uint8 SIZEOF_CHUNK = sizeof(chunk_t)*8;
|
||||
|
||||
public:
|
||||
enum flags_t : uint16 {
|
||||
HIDDEN = 0x0800
|
||||
};
|
||||
FeatureRef() throw();
|
||||
FeatureRef(const Face & face, unsigned short & bits_offset, uint32 max_val,
|
||||
uint32 name, uint16 uiName, flags_t flags,
|
||||
FeatureSetting *settings, uint16 num_set) throw();
|
||||
~FeatureRef() throw();
|
||||
|
||||
bool applyValToFeature(uint32 val, Features& pDest) const; //defined in GrFaceImp.h
|
||||
void maskFeature(Features & pDest) const {
|
||||
if (m_index < pDest.size()) //defensive
|
||||
pDest[m_index] |= m_mask;
|
||||
}
|
||||
|
||||
uint32 getFeatureVal(const Features& feats) const; //defined in GrFaceImp.h
|
||||
|
||||
uint32 getId() const { return m_id; }
|
||||
uint16 getNameId() const { return m_nameid; }
|
||||
uint16 getNumSettings() const { return m_numSet; }
|
||||
uint16 getSettingName(uint16 index) const { return m_nameValues[index].label(); }
|
||||
int16 getSettingValue(uint16 index) const { return m_nameValues[index].value(); }
|
||||
flags_t getFlags() const { return m_flags; }
|
||||
uint32 maxVal() const { return m_max; }
|
||||
const Face & getFace() const { assert(m_face); return *m_face;}
|
||||
const FeatureMap* getFeatureMap() const;// { return m_pFace;}
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
FeatureRef(const FeatureRef & rhs);
|
||||
|
||||
const Face * m_face;
|
||||
FeatureSetting * m_nameValues; // array of name table ids for feature values
|
||||
chunk_t m_mask, // bit mask to get the value from the vector
|
||||
m_max; // max value the value can take
|
||||
uint32 m_id; // feature identifier/name
|
||||
uint16 m_nameid, // Name table id for feature name
|
||||
m_numSet; // number of values (number of entries in m_nameValues)
|
||||
flags_t m_flags; // feature flags see FeatureRef::flags_t.
|
||||
byte m_bits, // how many bits to shift the value into place
|
||||
m_index; // index into the array to find the ulong to mask
|
||||
|
||||
private: //unimplemented
|
||||
FeatureRef& operator=(const FeatureRef&);
|
||||
};
|
||||
|
||||
inline
|
||||
FeatureRef::FeatureRef() throw()
|
||||
: m_face(0),
|
||||
m_nameValues(0),
|
||||
m_mask(0), m_max(0),
|
||||
m_id(0), m_nameid(0), m_numSet(0),
|
||||
m_flags(flags_t(0)),
|
||||
m_bits(0), m_index(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
class NameAndFeatureRef
|
||||
{
|
||||
public:
|
||||
NameAndFeatureRef(uint32 name = 0) : m_name(name) , m_pFRef(NULL){}
|
||||
NameAndFeatureRef(FeatureRef const & p) : m_name(p.getId()), m_pFRef(&p) {}
|
||||
|
||||
bool operator<(const NameAndFeatureRef& rhs) const //orders by m_name
|
||||
{ return m_name<rhs.m_name; }
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
|
||||
uint32 m_name;
|
||||
const FeatureRef* m_pFRef;
|
||||
};
|
||||
|
||||
class FeatureMap
|
||||
{
|
||||
public:
|
||||
FeatureMap() : m_numFeats(0), m_feats(NULL), m_pNamedFeats(NULL) {}
|
||||
~FeatureMap() { delete[] m_feats; delete[] m_pNamedFeats; }
|
||||
|
||||
bool readFeats(const Face & face);
|
||||
const FeatureRef *findFeatureRef(uint32 name) const;
|
||||
FeatureRef *feature(uint16 index) const { return m_feats + index; }
|
||||
//GrFeatureRef *featureRef(byte index) { return index < m_numFeats ? m_feats + index : NULL; }
|
||||
const FeatureRef *featureRef(byte index) const { return index < m_numFeats ? m_feats + index : NULL; }
|
||||
FeatureVal* cloneFeatures(uint32 langname/*0 means default*/) const; //call destroy_Features when done.
|
||||
uint16 numFeats() const { return m_numFeats; };
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
friend class SillMap;
|
||||
uint16 m_numFeats;
|
||||
|
||||
FeatureRef *m_feats;
|
||||
NameAndFeatureRef* m_pNamedFeats; //owned
|
||||
FeatureVal m_defaultFeatures; //owned
|
||||
|
||||
private: //defensive on m_feats, m_pNamedFeats, and m_defaultFeatures
|
||||
FeatureMap(const FeatureMap&);
|
||||
FeatureMap& operator=(const FeatureMap&);
|
||||
};
|
||||
|
||||
|
||||
class SillMap
|
||||
{
|
||||
private:
|
||||
class LangFeaturePair
|
||||
{
|
||||
LangFeaturePair(const LangFeaturePair &);
|
||||
LangFeaturePair & operator = (const LangFeaturePair &);
|
||||
|
||||
public:
|
||||
LangFeaturePair() : m_lang(0), m_pFeatures(0) {}
|
||||
~LangFeaturePair() { delete m_pFeatures; }
|
||||
|
||||
uint32 m_lang;
|
||||
Features* m_pFeatures; //owns
|
||||
CLASS_NEW_DELETE
|
||||
};
|
||||
public:
|
||||
SillMap() : m_langFeats(NULL), m_numLanguages(0) {}
|
||||
~SillMap() { delete[] m_langFeats; }
|
||||
bool readFace(const Face & face);
|
||||
bool readSill(const Face & face);
|
||||
FeatureVal* cloneFeatures(uint32 langname/*0 means default*/) const; //call destroy_Features when done.
|
||||
uint16 numLanguages() const { return m_numLanguages; };
|
||||
uint32 getLangName(uint16 index) const { return (index < m_numLanguages)? m_langFeats[index].m_lang : 0; };
|
||||
|
||||
const FeatureMap & theFeatureMap() const { return m_FeatureMap; };
|
||||
private:
|
||||
FeatureMap m_FeatureMap; //of face
|
||||
LangFeaturePair * m_langFeats;
|
||||
uint16 m_numLanguages;
|
||||
|
||||
private: //defensive on m_langFeats
|
||||
SillMap(const SillMap&);
|
||||
SillMap& operator=(const SillMap&);
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
struct gr_feature_ref : public graphite2::FeatureRef {};
|
45
thirdparty/graphite/src/inc/FeatureVal.h
vendored
Normal file
45
thirdparty/graphite/src/inc/FeatureVal.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "inc/Main.h"
|
||||
#include "inc/List.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class FeatureRef;
|
||||
class FeatureMap;
|
||||
|
||||
class FeatureVal : public Vector<uint32>
|
||||
{
|
||||
public:
|
||||
FeatureVal() : m_pMap(0) { }
|
||||
FeatureVal(int num, const FeatureMap & pMap) : Vector<uint32>(num), m_pMap(&pMap) {}
|
||||
FeatureVal(const FeatureVal & rhs) : Vector<uint32>(rhs), m_pMap(rhs.m_pMap) {}
|
||||
|
||||
FeatureVal & operator = (const FeatureVal & rhs) { Vector<uint32>::operator = (rhs); m_pMap = rhs.m_pMap; return *this; }
|
||||
|
||||
bool operator ==(const FeatureVal & b) const
|
||||
{
|
||||
size_t n = size();
|
||||
if (n != b.size()) return false;
|
||||
|
||||
for(const_iterator l = begin(), r = b.begin(); n && *l == *r; --n, ++l, ++r);
|
||||
|
||||
return n == 0;
|
||||
}
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
friend class FeatureRef; //so that FeatureRefs can manipulate m_vec directly
|
||||
const FeatureMap* m_pMap;
|
||||
};
|
||||
|
||||
typedef FeatureVal Features;
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
|
||||
struct gr_feature_val : public graphite2::FeatureVal {};
|
57
thirdparty/graphite/src/inc/FileFace.h
vendored
Normal file
57
thirdparty/graphite/src/inc/FileFace.h
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2012, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
//#include "inc/FeatureMap.h"
|
||||
//#include "inc/GlyphsCache.h"
|
||||
//#include "inc/Silf.h"
|
||||
|
||||
#ifndef GRAPHITE2_NFILEFACE
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#include "graphite2/Font.h"
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/TtfTypes.h"
|
||||
#include "inc/TtfUtil.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
|
||||
class FileFace
|
||||
{
|
||||
static const void * get_table_fn(const void* appFaceHandle, unsigned int name, size_t *len);
|
||||
static void rel_table_fn(const void* appFaceHandle, const void *table_buffer);
|
||||
|
||||
public:
|
||||
static const gr_face_ops ops;
|
||||
|
||||
FileFace(const char *filename);
|
||||
~FileFace();
|
||||
|
||||
operator bool () const throw();
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
private: //defensive
|
||||
FILE * _file;
|
||||
size_t _file_len;
|
||||
|
||||
TtfUtil::Sfnt::OffsetSubTable * _header_tbl;
|
||||
TtfUtil::Sfnt::OffsetSubTable::Entry * _table_dir;
|
||||
|
||||
FileFace(const FileFace&);
|
||||
FileFace& operator=(const FileFace&);
|
||||
};
|
||||
|
||||
inline
|
||||
FileFace::operator bool() const throw()
|
||||
{
|
||||
return _file && _header_tbl && _table_dir;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
#endif //!GRAPHITE2_NFILEFACE
|
67
thirdparty/graphite/src/inc/Font.h
vendored
Normal file
67
thirdparty/graphite/src/inc/Font.h
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include <cassert>
|
||||
#include "graphite2/Font.h"
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Face.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
#define INVALID_ADVANCE -1e38f // can't be a static const because non-integral
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
Font(float ppm, const Face & face, const void * appFontHandle=0, const gr_font_ops * ops=0);
|
||||
virtual ~Font();
|
||||
|
||||
float advance(unsigned short glyphid) const;
|
||||
float scale() const;
|
||||
bool isHinted() const;
|
||||
const Face & face() const;
|
||||
operator bool () const throw() { return m_advances; }
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
gr_font_ops m_ops;
|
||||
const void * const m_appFontHandle;
|
||||
float * m_advances; // One advance per glyph in pixels. Nan if not defined
|
||||
const Face & m_face;
|
||||
float m_scale; // scales from design units to ppm
|
||||
bool m_hinted;
|
||||
|
||||
Font(const Font&);
|
||||
Font& operator=(const Font&);
|
||||
};
|
||||
|
||||
inline
|
||||
float Font::advance(unsigned short glyphid) const
|
||||
{
|
||||
if (m_advances[glyphid] == INVALID_ADVANCE)
|
||||
m_advances[glyphid] = (*m_ops.glyph_advance_x)(m_appFontHandle, glyphid);
|
||||
return m_advances[glyphid];
|
||||
}
|
||||
|
||||
inline
|
||||
float Font::scale() const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
inline
|
||||
bool Font::isHinted() const
|
||||
{
|
||||
return m_hinted;
|
||||
}
|
||||
|
||||
inline
|
||||
const Face & Font::face() const
|
||||
{
|
||||
return m_face;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
struct gr_font : public graphite2::Font {};
|
200
thirdparty/graphite/src/inc/GlyphCache.h
vendored
Normal file
200
thirdparty/graphite/src/inc/GlyphCache.h
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2012, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "graphite2/Font.h"
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Position.h"
|
||||
#include "inc/GlyphFace.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Face;
|
||||
class FeatureVal;
|
||||
class Segment;
|
||||
|
||||
|
||||
struct SlantBox
|
||||
{
|
||||
static const SlantBox empty;
|
||||
|
||||
// SlantBox(float psi = 0., float pdi = 0., float psa = 0., float pda = 0.) : si(psi), di(pdi), sa(psa), da(pda) {};
|
||||
float width() const { return sa - si; }
|
||||
float height() const { return da - di; }
|
||||
float si; // min
|
||||
float di; // min
|
||||
float sa; // max
|
||||
float da; // max
|
||||
};
|
||||
|
||||
|
||||
struct BBox
|
||||
{
|
||||
BBox(float pxi = 0, float pyi = 0., float pxa = 0., float pya = 0.) : xi(pxi), yi(pyi), xa(pxa), ya(pya) {};
|
||||
float width() const { return xa - xi; }
|
||||
float height() const { return ya - yi; }
|
||||
float xi; // min
|
||||
float yi; // min
|
||||
float xa; // max
|
||||
float ya; // max
|
||||
};
|
||||
|
||||
|
||||
class GlyphBox
|
||||
{
|
||||
GlyphBox(const GlyphBox &);
|
||||
GlyphBox & operator = (const GlyphBox &);
|
||||
|
||||
public:
|
||||
GlyphBox(uint8 numsubs, unsigned short bitmap, Rect *slanted) : _num(numsubs), _bitmap(bitmap), _slant(*slanted) {};
|
||||
|
||||
void addSubBox(int subindex, int boundary, Rect *val) { _subs[subindex * 2 + boundary] = *val; }
|
||||
Rect &subVal(int subindex, int boundary) { return _subs[subindex * 2 + boundary]; }
|
||||
const Rect &slant() const { return _slant; }
|
||||
uint8 num() const { return _num; }
|
||||
const Rect *subs() const { return _subs; }
|
||||
|
||||
private:
|
||||
uint8 _num;
|
||||
unsigned short _bitmap;
|
||||
Rect _slant;
|
||||
Rect _subs[1];
|
||||
};
|
||||
|
||||
class GlyphCache
|
||||
{
|
||||
class Loader;
|
||||
|
||||
GlyphCache(const GlyphCache&);
|
||||
GlyphCache& operator=(const GlyphCache&);
|
||||
|
||||
public:
|
||||
GlyphCache(const Face & face, const uint32 face_options);
|
||||
~GlyphCache();
|
||||
|
||||
unsigned short numGlyphs() const throw();
|
||||
unsigned short numAttrs() const throw();
|
||||
unsigned short unitsPerEm() const throw();
|
||||
|
||||
const GlyphFace *glyph(unsigned short glyphid) const; //result may be changed by subsequent call with a different glyphid
|
||||
const GlyphFace *glyphSafe(unsigned short glyphid) const;
|
||||
float getBoundingMetric(unsigned short glyphid, uint8 metric) const;
|
||||
uint8 numSubBounds(unsigned short glyphid) const;
|
||||
float getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const;
|
||||
const Rect & slant(unsigned short glyphid) const { return _boxes[glyphid] ? _boxes[glyphid]->slant() : _empty_slant_box; }
|
||||
const SlantBox & getBoundingSlantBox(unsigned short glyphid) const;
|
||||
const BBox & getBoundingBBox(unsigned short glyphid) const;
|
||||
const SlantBox & getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const;
|
||||
const BBox & getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const;
|
||||
bool check(unsigned short glyphid) const;
|
||||
bool hasBoxes() const { return _boxes != 0; }
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
private:
|
||||
const Rect _empty_slant_box;
|
||||
const Loader * _glyph_loader;
|
||||
const GlyphFace * * _glyphs;
|
||||
GlyphBox * * _boxes;
|
||||
unsigned short _num_glyphs,
|
||||
_num_attrs,
|
||||
_upem;
|
||||
};
|
||||
|
||||
inline
|
||||
unsigned short GlyphCache::numGlyphs() const throw()
|
||||
{
|
||||
return _num_glyphs;
|
||||
}
|
||||
|
||||
inline
|
||||
unsigned short GlyphCache::numAttrs() const throw()
|
||||
{
|
||||
return _num_attrs;
|
||||
}
|
||||
|
||||
inline
|
||||
unsigned short GlyphCache::unitsPerEm() const throw()
|
||||
{
|
||||
return _upem;
|
||||
}
|
||||
|
||||
inline
|
||||
bool GlyphCache::check(unsigned short glyphid) const
|
||||
{
|
||||
return _boxes && glyphid < _num_glyphs;
|
||||
}
|
||||
|
||||
inline
|
||||
const GlyphFace *GlyphCache::glyphSafe(unsigned short glyphid) const
|
||||
{
|
||||
return glyphid < _num_glyphs ? glyph(glyphid) : NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
float GlyphCache::getBoundingMetric(unsigned short glyphid, uint8 metric) const
|
||||
{
|
||||
if (glyphid >= _num_glyphs) return 0.;
|
||||
switch (metric) {
|
||||
case 0: return (float)(glyph(glyphid)->theBBox().bl.x); // x_min
|
||||
case 1: return (float)(glyph(glyphid)->theBBox().bl.y); // y_min
|
||||
case 2: return (float)(glyph(glyphid)->theBBox().tr.x); // x_max
|
||||
case 3: return (float)(glyph(glyphid)->theBBox().tr.y); // y_max
|
||||
case 4: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.x : 0.f); // sum_min
|
||||
case 5: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.y : 0.f); // diff_min
|
||||
case 6: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.x : 0.f); // sum_max
|
||||
case 7: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.y : 0.f); // diff_max
|
||||
default: return 0.;
|
||||
}
|
||||
}
|
||||
|
||||
inline const SlantBox &GlyphCache::getBoundingSlantBox(unsigned short glyphid) const
|
||||
{
|
||||
return _boxes[glyphid] ? *(SlantBox *)(&(_boxes[glyphid]->slant())) : SlantBox::empty;
|
||||
}
|
||||
|
||||
inline const BBox &GlyphCache::getBoundingBBox(unsigned short glyphid) const
|
||||
{
|
||||
return *(BBox *)(&(glyph(glyphid)->theBBox()));
|
||||
}
|
||||
|
||||
inline
|
||||
float GlyphCache::getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const
|
||||
{
|
||||
GlyphBox *b = _boxes[glyphid];
|
||||
if (b == NULL || subindex >= b->num()) return 0;
|
||||
|
||||
switch (metric) {
|
||||
case 0: return b->subVal(subindex, 0).bl.x;
|
||||
case 1: return b->subVal(subindex, 0).bl.y;
|
||||
case 2: return b->subVal(subindex, 0).tr.x;
|
||||
case 3: return b->subVal(subindex, 0).tr.y;
|
||||
case 4: return b->subVal(subindex, 1).bl.x;
|
||||
case 5: return b->subVal(subindex, 1).bl.y;
|
||||
case 6: return b->subVal(subindex, 1).tr.x;
|
||||
case 7: return b->subVal(subindex, 1).tr.y;
|
||||
default: return 0.;
|
||||
}
|
||||
}
|
||||
|
||||
inline const SlantBox &GlyphCache::getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const
|
||||
{
|
||||
GlyphBox *b = _boxes[glyphid];
|
||||
return *(SlantBox *)(b->subs() + 2 * subindex + 1);
|
||||
}
|
||||
|
||||
inline const BBox &GlyphCache::getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const
|
||||
{
|
||||
GlyphBox *b = _boxes[glyphid];
|
||||
return *(BBox *)(b->subs() + 2 * subindex);
|
||||
}
|
||||
|
||||
inline
|
||||
uint8 GlyphCache::numSubBounds(unsigned short glyphid) const
|
||||
{
|
||||
return _boxes[glyphid] ? _boxes[glyphid]->num() : 0;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
60
thirdparty/graphite/src/inc/GlyphFace.h
vendored
Normal file
60
thirdparty/graphite/src/inc/GlyphFace.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Position.h"
|
||||
#include "inc/Sparse.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
enum metrics {
|
||||
kgmetLsb = 0, kgmetRsb,
|
||||
kgmetBbTop, kgmetBbBottom, kgmetBbLeft, kgmetBbRight,
|
||||
kgmetBbHeight, kgmetBbWidth,
|
||||
kgmetAdvWidth, kgmetAdvHeight,
|
||||
kgmetAscent, kgmetDescent
|
||||
};
|
||||
|
||||
|
||||
class GlyphFace
|
||||
{
|
||||
public:
|
||||
GlyphFace();
|
||||
template<typename I>
|
||||
GlyphFace(const Rect & bbox, const Position & adv, I first, const I last);
|
||||
|
||||
const Position & theAdvance() const;
|
||||
const Rect & theBBox() const { return m_bbox; }
|
||||
const sparse & attrs() const { return m_attrs; }
|
||||
int32 getMetric(uint8 metric) const;
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
Rect m_bbox; // bounding box metrics in design units
|
||||
Position m_advance; // Advance width and height in design units
|
||||
sparse m_attrs;
|
||||
};
|
||||
|
||||
|
||||
// Inlines: class GlyphFace
|
||||
//
|
||||
inline
|
||||
GlyphFace::GlyphFace()
|
||||
{}
|
||||
|
||||
template<typename I>
|
||||
GlyphFace::GlyphFace(const Rect & bbox, const Position & adv, I first, const I last)
|
||||
: m_bbox(bbox),
|
||||
m_advance(adv),
|
||||
m_attrs(first, last)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
const Position & GlyphFace::theAdvance() const {
|
||||
return m_advance;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
211
thirdparty/graphite/src/inc/Intervals.h
vendored
Normal file
211
thirdparty/graphite/src/inc/Intervals.h
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/List.h"
|
||||
#include "inc/json.h"
|
||||
#include "inc/Position.h"
|
||||
|
||||
// An IntervalSet represents the possible movement of a given glyph in a given direction
|
||||
// (horizontally, vertically, or diagonally).
|
||||
// A vector is needed to represent disjoint ranges, eg, -300..-150, 20..200, 500..750.
|
||||
// Each pair represents the min/max of a sub-range.
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Segment;
|
||||
|
||||
enum zones_t {SD, XY};
|
||||
|
||||
class Zones
|
||||
{
|
||||
struct Exclusion
|
||||
{
|
||||
template<zones_t O>
|
||||
static Exclusion weighted(float xmin, float xmax, float f, float a0,
|
||||
float m, float xi, float ai, float c, bool nega);
|
||||
|
||||
float x, // x position
|
||||
xm, // xmax position
|
||||
c, // constant + sum(MiXi^2)
|
||||
sm, // sum(Mi)
|
||||
smx; // sum(MiXi)
|
||||
bool open;
|
||||
|
||||
Exclusion(float x, float w, float smi, float smxi, float c);
|
||||
Exclusion & operator += (Exclusion const & rhs);
|
||||
uint8 outcode(float p) const;
|
||||
|
||||
Exclusion split_at(float p);
|
||||
void left_trim(float p);
|
||||
|
||||
bool track_cost(float & cost, float & x, float origin) const;
|
||||
|
||||
private:
|
||||
float test_position(float origin) const;
|
||||
float cost(float x) const;
|
||||
};
|
||||
|
||||
typedef Vector<Exclusion> exclusions;
|
||||
|
||||
typedef exclusions::iterator iterator;
|
||||
typedef Exclusion * pointer;
|
||||
typedef Exclusion & reference;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
|
||||
public:
|
||||
typedef exclusions::const_iterator const_iterator;
|
||||
typedef Exclusion const * const_pointer;
|
||||
typedef Exclusion const & const_reference;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
struct Debug
|
||||
{
|
||||
Exclusion _excl;
|
||||
bool _isdel;
|
||||
Vector<void *> _env;
|
||||
|
||||
Debug(Exclusion *e, bool isdel, json *dbg) : _excl(*e), _isdel(isdel), _env(dbg->getenvs()) { };
|
||||
};
|
||||
|
||||
typedef Vector<Debug> debugs;
|
||||
typedef debugs::const_iterator idebugs;
|
||||
void addDebug(Exclusion *e);
|
||||
void removeDebug(float pos, float posm);
|
||||
void setdebug(json *dbgout) { _dbg = dbgout; }
|
||||
idebugs dbgs_begin() const { return _dbgs.begin(); }
|
||||
idebugs dbgs_end() const { return _dbgs.end(); }
|
||||
void jsonDbgOut(Segment *seg) const;
|
||||
Position position() const { return Position(_pos, _posm); }
|
||||
#endif
|
||||
|
||||
Zones();
|
||||
template<zones_t O>
|
||||
void initialise(float xmin, float xmax, float margin_len, float margin_weight, float ao);
|
||||
|
||||
void exclude(float xmin, float xmax);
|
||||
void exclude_with_margins(float xmin, float xmax, int axis);
|
||||
|
||||
template<zones_t O>
|
||||
void weighted(float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);
|
||||
void weightedAxis(int axis, float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);
|
||||
|
||||
float closest( float origin, float &cost) const;
|
||||
|
||||
const_iterator begin() const { return _exclusions.begin(); }
|
||||
const_iterator end() const { return _exclusions.end(); }
|
||||
|
||||
private:
|
||||
exclusions _exclusions;
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
json * _dbg;
|
||||
debugs _dbgs;
|
||||
#endif
|
||||
float _margin_len,
|
||||
_margin_weight,
|
||||
_pos,
|
||||
_posm;
|
||||
|
||||
void insert(Exclusion e);
|
||||
void remove(float x, float xm);
|
||||
const_iterator find_exclusion_under(float x) const;
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
Zones::Zones()
|
||||
: _margin_len(0), _margin_weight(0), _pos(0), _posm(0)
|
||||
{
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
_dbg = 0;
|
||||
#endif
|
||||
_exclusions.reserve(8);
|
||||
}
|
||||
|
||||
inline
|
||||
Zones::Exclusion::Exclusion(float x_, float xm_, float smi, float smxi, float c_)
|
||||
: x(x_), xm(xm_), c(c_), sm(smi), smx(smxi), open(false)
|
||||
{ }
|
||||
|
||||
template<zones_t O>
|
||||
inline
|
||||
void Zones::initialise(float xmin, float xmax, float margin_len,
|
||||
float margin_weight, float a0)
|
||||
{
|
||||
_margin_len = margin_len;
|
||||
_margin_weight = margin_weight;
|
||||
_pos = xmin;
|
||||
_posm = xmax;
|
||||
_exclusions.clear();
|
||||
_exclusions.push_back(Exclusion::weighted<O>(xmin, xmax, 1, a0, 0, 0, 0, 0, false));
|
||||
_exclusions.front().open = true;
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
_dbgs.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
void Zones::exclude(float xmin, float xmax) {
|
||||
remove(xmin, xmax);
|
||||
}
|
||||
|
||||
template<zones_t O>
|
||||
inline
|
||||
void Zones::weighted(float xmin, float xmax, float f, float a0,
|
||||
float m, float xi, float ai, float c, bool nega) {
|
||||
insert(Exclusion::weighted<O>(xmin, xmax, f, a0, m, xi, ai, c, nega));
|
||||
}
|
||||
|
||||
inline
|
||||
void Zones::weightedAxis(int axis, float xmin, float xmax, float f, float a0,
|
||||
float m, float xi, float ai, float c, bool nega) {
|
||||
if (axis < 2)
|
||||
weighted<XY>(xmin, xmax, f, a0, m, xi, ai, c, nega);
|
||||
else
|
||||
weighted<SD>(xmin, xmax, f, a0, m, xi, ai, c, nega);
|
||||
}
|
||||
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
inline
|
||||
void Zones::addDebug(Exclusion *e) {
|
||||
if (_dbg)
|
||||
_dbgs.push_back(Debug(e, false, _dbg));
|
||||
}
|
||||
|
||||
inline
|
||||
void Zones::removeDebug(float pos, float posm) {
|
||||
if (_dbg)
|
||||
{
|
||||
Exclusion e(pos, posm, 0, 0, 0);
|
||||
_dbgs.push_back(Debug(&e, true, _dbg));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<>
|
||||
inline
|
||||
Zones::Exclusion Zones::Exclusion::weighted<XY>(float xmin, float xmax, float f, float a0,
|
||||
float m, float xi, GR_MAYBE_UNUSED float ai, float c, GR_MAYBE_UNUSED bool nega) {
|
||||
return Exclusion(xmin, xmax,
|
||||
m + f,
|
||||
m * xi,
|
||||
m * xi * xi + f * a0 * a0 + c);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
Zones::Exclusion Zones::Exclusion::weighted<SD>(float xmin, float xmax, float f, float a0,
|
||||
float m, float xi, float ai,float c, bool nega) {
|
||||
float xia = nega ? xi - ai : xi + ai;
|
||||
return Exclusion(xmin, xmax,
|
||||
0.25f * (m + 2.f * f),
|
||||
0.25f * m * xia,
|
||||
0.25f * (m * xia * xia + 2.f * f * a0 * a0) + c);
|
||||
}
|
||||
|
||||
} // end of namespace graphite2
|
145
thirdparty/graphite/src/inc/List.h
vendored
Normal file
145
thirdparty/graphite/src/inc/List.h
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
|
||||
// designed to have a limited subset of the std::vector api
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
||||
#include "Main.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
template <typename T>
|
||||
inline
|
||||
ptrdiff_t distance(T* first, T* last) { return last-first; }
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Vector
|
||||
{
|
||||
T * m_first, *m_last, *m_end;
|
||||
public:
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef T * iterator;
|
||||
typedef const T * const_iterator;
|
||||
|
||||
Vector() : m_first(0), m_last(0), m_end(0) {}
|
||||
Vector(size_t n, const T& value = T()) : m_first(0), m_last(0), m_end(0) { insert(begin(), n, value); }
|
||||
Vector(const Vector<T> &rhs) : m_first(0), m_last(0), m_end(0) { insert(begin(), rhs.begin(), rhs.end()); }
|
||||
template <typename I>
|
||||
Vector(I first, const I last) : m_first(0), m_last(0), m_end(0) { insert(begin(), first, last); }
|
||||
~Vector() { clear(); free(m_first); }
|
||||
|
||||
iterator begin() { return m_first; }
|
||||
const_iterator begin() const { return m_first; }
|
||||
|
||||
iterator end() { return m_last; }
|
||||
const_iterator end() const { return m_last; }
|
||||
|
||||
bool empty() const { return m_first == m_last; }
|
||||
size_t size() const { return m_last - m_first; }
|
||||
size_t capacity() const{ return m_end - m_first; }
|
||||
|
||||
void reserve(size_t n);
|
||||
void resize(size_t n, const T & v = T());
|
||||
|
||||
reference front() { assert(size() > 0); return *begin(); }
|
||||
const_reference front() const { assert(size() > 0); return *begin(); }
|
||||
reference back() { assert(size() > 0); return *(end()-1); }
|
||||
const_reference back() const { assert(size() > 0); return *(end()-1); }
|
||||
|
||||
Vector<T> & operator = (const Vector<T> & rhs) { assign(rhs.begin(), rhs.end()); return *this; }
|
||||
reference operator [] (size_t n) { assert(size() > n); return m_first[n]; }
|
||||
const_reference operator [] (size_t n) const { assert(size() > n); return m_first[n]; }
|
||||
|
||||
void assign(size_t n, const T& u) { clear(); insert(begin(), n, u); }
|
||||
void assign(const_iterator first, const_iterator last) { clear(); insert(begin(), first, last); }
|
||||
iterator insert(iterator p, const T & x) { p = _insert_default(p, 1); new (p) T(x); return p; }
|
||||
void insert(iterator p, size_t n, const T & x);
|
||||
void insert(iterator p, const_iterator first, const_iterator last);
|
||||
void pop_back() { assert(size() > 0); --m_last; }
|
||||
void push_back(const T &v) { if (m_last == m_end) reserve(size()+1); new (m_last++) T(v); }
|
||||
|
||||
void clear() { erase(begin(), end()); }
|
||||
iterator erase(iterator p) { return erase(p, p+1); }
|
||||
iterator erase(iterator first, iterator last);
|
||||
|
||||
private:
|
||||
iterator _insert_default(iterator p, size_t n);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline
|
||||
void Vector<T>::reserve(size_t n)
|
||||
{
|
||||
if (n > capacity())
|
||||
{
|
||||
const ptrdiff_t sz = size();
|
||||
size_t requested;
|
||||
if (checked_mul(n,sizeof(T), requested)) std::abort();
|
||||
m_first = static_cast<T*>(realloc(m_first, requested));
|
||||
if (!m_first) std::abort();
|
||||
m_last = m_first + sz;
|
||||
m_end = m_first + n;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline
|
||||
void Vector<T>::resize(size_t n, const T & v) {
|
||||
const ptrdiff_t d = n-size();
|
||||
if (d < 0) erase(end()+d, end());
|
||||
else if (d > 0) insert(end(), d, v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
typename Vector<T>::iterator Vector<T>::_insert_default(iterator p, size_t n)
|
||||
{
|
||||
assert(begin() <= p && p <= end());
|
||||
const ptrdiff_t i = p - begin();
|
||||
reserve(((size() + n + 7) >> 3) << 3);
|
||||
p = begin() + i;
|
||||
// Move tail if there is one
|
||||
if (p != end()) memmove(p + n, p, distance(p,end())*sizeof(T));
|
||||
m_last += n;
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
void Vector<T>::insert(iterator p, size_t n, const T & x)
|
||||
{
|
||||
p = _insert_default(p, n);
|
||||
// Copy in elements
|
||||
for (; n; --n, ++p) { new (p) T(x); }
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
void Vector<T>::insert(iterator p, const_iterator first, const_iterator last)
|
||||
{
|
||||
p = _insert_default(p, distance(first, last));
|
||||
// Copy in elements
|
||||
for (;first != last; ++first, ++p) { new (p) T(*first); }
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
typename Vector<T>::iterator Vector<T>::erase(iterator first, iterator last)
|
||||
{
|
||||
for (iterator e = first; e != last; ++e) e->~T();
|
||||
const size_t sz = distance(first, last);
|
||||
if (m_last != last) memmove(first, last, distance(last,end())*sizeof(T));
|
||||
m_last -= sz;
|
||||
return first;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
184
thirdparty/graphite/src/inc/Machine.h
vendored
Normal file
184
thirdparty/graphite/src/inc/Machine.h
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
// This general interpreter interface.
|
||||
// Author: Tim Eves
|
||||
|
||||
// Build one of direct_machine.cpp or call_machine.cpp to implement this
|
||||
// interface.
|
||||
|
||||
#pragma once
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <graphite2/Types.h>
|
||||
#include "inc/Main.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ * 10) < 430
|
||||
#define HOT
|
||||
#if defined(__x86_64)
|
||||
#define REGPARM(n) __attribute__((regparm(n)))
|
||||
#else
|
||||
#define REGPARM(n)
|
||||
#endif
|
||||
#else
|
||||
#define HOT __attribute__((hot))
|
||||
#if defined(__x86_64)
|
||||
#define REGPARM(n) __attribute__((hot, regparm(n)))
|
||||
#else
|
||||
#define REGPARM(n)
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define HOT
|
||||
#define REGPARM(n)
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
// MinGW's <limits> at some point includes winnt.h which #define's a
|
||||
// DELETE macro, which conflicts with enum opcode below, so we undefine
|
||||
// it here.
|
||||
#undef DELETE
|
||||
#endif
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
// Forward declarations
|
||||
class Segment;
|
||||
class Slot;
|
||||
class SlotMap;
|
||||
|
||||
|
||||
namespace vm
|
||||
{
|
||||
|
||||
|
||||
typedef void * instr;
|
||||
typedef Slot * slotref;
|
||||
|
||||
enum {VARARGS = 0xff, MAX_NAME_LEN=32};
|
||||
|
||||
enum opcode {
|
||||
NOP = 0,
|
||||
|
||||
PUSH_BYTE, PUSH_BYTEU, PUSH_SHORT, PUSH_SHORTU, PUSH_LONG,
|
||||
|
||||
ADD, SUB, MUL, DIV,
|
||||
MIN_, MAX_,
|
||||
NEG,
|
||||
TRUNC8, TRUNC16,
|
||||
|
||||
COND,
|
||||
|
||||
AND, OR, NOT,
|
||||
EQUAL, NOT_EQ,
|
||||
LESS, GTR, LESS_EQ, GTR_EQ,
|
||||
|
||||
NEXT, NEXT_N, COPY_NEXT,
|
||||
PUT_GLYPH_8BIT_OBS, PUT_SUBS_8BIT_OBS, PUT_COPY,
|
||||
INSERT, DELETE,
|
||||
ASSOC,
|
||||
CNTXT_ITEM,
|
||||
|
||||
ATTR_SET, ATTR_ADD, ATTR_SUB,
|
||||
ATTR_SET_SLOT,
|
||||
IATTR_SET_SLOT,
|
||||
PUSH_SLOT_ATTR, PUSH_GLYPH_ATTR_OBS,
|
||||
PUSH_GLYPH_METRIC, PUSH_FEAT,
|
||||
PUSH_ATT_TO_GATTR_OBS, PUSH_ATT_TO_GLYPH_METRIC,
|
||||
PUSH_ISLOT_ATTR,
|
||||
|
||||
PUSH_IGLYPH_ATTR, // not implemented
|
||||
|
||||
POP_RET, RET_ZERO, RET_TRUE,
|
||||
IATTR_SET, IATTR_ADD, IATTR_SUB,
|
||||
PUSH_PROC_STATE, PUSH_VERSION,
|
||||
PUT_SUBS, PUT_SUBS2, PUT_SUBS3,
|
||||
PUT_GLYPH, PUSH_GLYPH_ATTR, PUSH_ATT_TO_GLYPH_ATTR,
|
||||
BITOR, BITAND, BITNOT,
|
||||
BITSET, SET_FEAT,
|
||||
MAX_OPCODE,
|
||||
// private opcodes for internal use only, comes after all other on disk opcodes
|
||||
TEMP_COPY = MAX_OPCODE
|
||||
};
|
||||
|
||||
struct opcode_t
|
||||
{
|
||||
instr impl[2];
|
||||
uint8 param_sz;
|
||||
char name[MAX_NAME_LEN];
|
||||
};
|
||||
|
||||
|
||||
class Machine
|
||||
{
|
||||
public:
|
||||
typedef int32 stack_t;
|
||||
static size_t const STACK_ORDER = 10,
|
||||
STACK_MAX = 1 << STACK_ORDER,
|
||||
STACK_GUARD = 2;
|
||||
|
||||
class Code;
|
||||
|
||||
enum status_t {
|
||||
finished = 0,
|
||||
stack_underflow,
|
||||
stack_not_empty,
|
||||
stack_overflow,
|
||||
slot_offset_out_bounds,
|
||||
died_early
|
||||
};
|
||||
|
||||
Machine(SlotMap &) throw();
|
||||
static const opcode_t * getOpcodeTable() throw();
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
SlotMap & slotMap() const throw();
|
||||
status_t status() const throw();
|
||||
// operator bool () const throw();
|
||||
|
||||
private:
|
||||
void check_final_stack(const stack_t * const sp);
|
||||
stack_t run(const instr * program, const byte * data,
|
||||
slotref * & map) HOT;
|
||||
|
||||
SlotMap & _map;
|
||||
stack_t _stack[STACK_MAX + 2*STACK_GUARD];
|
||||
status_t _status;
|
||||
};
|
||||
|
||||
inline Machine::Machine(SlotMap & map) throw()
|
||||
: _map(map), _status(finished)
|
||||
{
|
||||
// Initialise stack guard +1 entries as the stack pointer points to the
|
||||
// current top of stack, hence the first push will never write entry 0.
|
||||
// Initialising the guard space like this is unnecessary and is only
|
||||
// done to keep valgrind happy during fuzz testing. Hopefully loop
|
||||
// unrolling will flatten this.
|
||||
for (size_t n = STACK_GUARD + 1; n; --n) _stack[n-1] = 0;
|
||||
}
|
||||
|
||||
inline SlotMap& Machine::slotMap() const throw()
|
||||
{
|
||||
return _map;
|
||||
}
|
||||
|
||||
inline Machine::status_t Machine::status() const throw()
|
||||
{
|
||||
return _status;
|
||||
}
|
||||
|
||||
inline void Machine::check_final_stack(const stack_t * const sp)
|
||||
{
|
||||
if (_status != finished) return;
|
||||
|
||||
stack_t const * const base = _stack + STACK_GUARD,
|
||||
* const limit = base + STACK_MAX;
|
||||
if (sp < base) _status = stack_underflow; // This should be impossible now.
|
||||
else if (sp >= limit) _status = stack_overflow; // So should this.
|
||||
else if (sp != base) _status = stack_not_empty;
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
} // namespace graphite2
|
176
thirdparty/graphite/src/inc/Main.h
vendored
Normal file
176
thirdparty/graphite/src/inc/Main.h
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include "graphite2/Types.h"
|
||||
|
||||
#ifdef GRAPHITE2_CUSTOM_HEADER
|
||||
#include GRAPHITE2_CUSTOM_HEADER
|
||||
#endif
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
typedef gr_uint8 uint8;
|
||||
typedef gr_uint8 byte;
|
||||
typedef gr_uint16 uint16;
|
||||
typedef gr_uint32 uint32;
|
||||
typedef gr_int8 int8;
|
||||
typedef gr_int16 int16;
|
||||
typedef gr_int32 int32;
|
||||
typedef size_t uintptr;
|
||||
|
||||
#ifdef GRAPHITE2_TELEMETRY
|
||||
struct telemetry
|
||||
{
|
||||
class category;
|
||||
|
||||
static size_t * _category;
|
||||
static void set_category(size_t & t) throw() { _category = &t; }
|
||||
static void stop() throw() { _category = 0; }
|
||||
static void count_bytes(size_t n) throw() { if (_category) *_category += n; }
|
||||
|
||||
size_t misc,
|
||||
silf,
|
||||
glyph,
|
||||
code,
|
||||
states,
|
||||
starts,
|
||||
transitions;
|
||||
|
||||
telemetry() : misc(0), silf(0), glyph(0), code(0), states(0), starts(0), transitions(0) {}
|
||||
};
|
||||
|
||||
class telemetry::category
|
||||
{
|
||||
size_t * _prev;
|
||||
public:
|
||||
category(size_t & t) : _prev(_category) { _category = &t; }
|
||||
~category() { _category = _prev; }
|
||||
};
|
||||
|
||||
#else
|
||||
struct telemetry {};
|
||||
#endif
|
||||
|
||||
// Checked multiplaction to catch overflow or underflow when allocating memory
|
||||
#if defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_mul_overflow)
|
||||
#define HAVE_BUILTIN_OVERFLOW
|
||||
#endif
|
||||
#elif defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__INTEL_COMPILER)
|
||||
#define HAVE_BUILTIN_OVERFLOW
|
||||
#endif
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<intsafe.h>) && !defined(__CYGWIN__)
|
||||
#define HAVE_INTSAFE_H
|
||||
#endif
|
||||
#elif defined(_WIN32)
|
||||
#define HAVE_INTSAFE_H
|
||||
#endif
|
||||
|
||||
// Need to import intsafe into the top level namespace
|
||||
#if defined(HAVE_INTSAFE_H)
|
||||
} // namespace graphite2
|
||||
|
||||
#include <intsafe.h>
|
||||
|
||||
namespace graphite2 {
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_BUILTIN_OVERFLOW)
|
||||
inline
|
||||
bool checked_mul(const size_t a, const size_t b, size_t & t) {
|
||||
return __builtin_mul_overflow(a, b, &t);
|
||||
}
|
||||
#elif defined(HAVE_INTSAFE_H)
|
||||
inline
|
||||
bool checked_mul(const size_t a, const size_t b, size_t & t) {
|
||||
return SizeTMult(a, b, &t) == INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
#else
|
||||
inline
|
||||
bool checked_mul(const size_t a, const size_t b, size_t & t) {
|
||||
t = a*b;
|
||||
return (((a | b) & (~size_t(0) << (sizeof(size_t) << 2))) && (t / a != b));
|
||||
}
|
||||
#endif
|
||||
|
||||
// typesafe wrapper around malloc for simple types
|
||||
// use free(pointer) to deallocate
|
||||
|
||||
template <typename T> T * gralloc(size_t n)
|
||||
{
|
||||
size_t total;
|
||||
if (checked_mul(n, sizeof(T), total))
|
||||
return 0;
|
||||
#ifdef GRAPHITE2_TELEMETRY
|
||||
telemetry::count_bytes(total);
|
||||
#endif
|
||||
return static_cast<T*>(malloc(total));
|
||||
}
|
||||
|
||||
template <typename T> T * grzeroalloc(size_t n)
|
||||
{
|
||||
#ifdef GRAPHITE2_TELEMETRY
|
||||
telemetry::count_bytes(sizeof(T) * n);
|
||||
#endif
|
||||
return static_cast<T*>(calloc(n, sizeof(T)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T min(const T a, const T b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T max(const T a, const T b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
#define CLASS_NEW_DELETE \
|
||||
void * operator new (size_t size){ return gralloc<byte>(size);} \
|
||||
void * operator new (size_t, void * p) throw() { return p; } \
|
||||
void * operator new[] (size_t size) {return gralloc<byte>(size);} \
|
||||
void * operator new[] (size_t, void * p) throw() { return p; } \
|
||||
void operator delete (void * p) throw() { free(p);} \
|
||||
void operator delete (void *, void *) throw() {} \
|
||||
void operator delete[] (void * p)throw() { free(p); } \
|
||||
void operator delete[] (void *, void *) throw() {}
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define GR_MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define GR_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef __has_cpp_attribute
|
||||
# define __has_cpp_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_cpp_attribute(clang::fallthrough)
|
||||
# define GR_FALLTHROUGH [[clang::fallthrough]]
|
||||
#elif __has_cpp_attribute(gnu::fallthrough)
|
||||
# define GR_FALLTHROUGH [[gnu::fallthrough]]
|
||||
#elif defined(_MSC_VER)
|
||||
/*
|
||||
* MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
|
||||
* https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
|
||||
*/
|
||||
#include <sal.h>
|
||||
#define GR_FALLTHROUGH __fallthrough
|
||||
#elif __GNUC__ >= 7
|
||||
#define GR_FALLTHROUGH __attribute__ ((fallthrough))
|
||||
#else
|
||||
#define GR_FALLTHROUGH /* fallthrough */
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4800)
|
||||
#pragma warning(disable: 4355)
|
||||
#endif
|
42
thirdparty/graphite/src/inc/NameTable.h
vendored
Normal file
42
thirdparty/graphite/src/inc/NameTable.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <graphite2/Segment.h>
|
||||
#include "inc/TtfTypes.h"
|
||||
#include "inc/locale2lcid.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class NameTable
|
||||
{
|
||||
NameTable(const NameTable &);
|
||||
NameTable & operator = (const NameTable &);
|
||||
|
||||
public:
|
||||
NameTable(const void * data, size_t length, uint16 platfromId=3, uint16 encodingID = 1);
|
||||
~NameTable() { free(const_cast<TtfUtil::Sfnt::FontNames *>(m_table)); }
|
||||
enum eNameFallback {
|
||||
eNoFallback = 0,
|
||||
eEnUSFallbackOnly = 1,
|
||||
eEnOrAnyFallback = 2
|
||||
};
|
||||
uint16 setPlatformEncoding(uint16 platfromId=3, uint16 encodingID = 1);
|
||||
void * getName(uint16 & languageId, uint16 nameId, gr_encform enc, uint32 & length);
|
||||
uint16 getLanguageId(const char * bcp47Locale);
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
uint16 m_platformId;
|
||||
uint16 m_encodingId;
|
||||
uint16 m_languageCount;
|
||||
uint16 m_platformOffset; // offset of first NameRecord with for platform 3, encoding 1
|
||||
uint16 m_platformLastRecord;
|
||||
uint16 m_nameDataLength;
|
||||
const TtfUtil::Sfnt::FontNames * m_table;
|
||||
const uint8 * m_nameData;
|
||||
Locale2Lang m_locale2Lang;
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
95
thirdparty/graphite/src/inc/Pass.h
vendored
Normal file
95
thirdparty/graphite/src/inc/Pass.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include "inc/Code.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Segment;
|
||||
class Face;
|
||||
class Silf;
|
||||
struct Rule;
|
||||
struct RuleEntry;
|
||||
struct State;
|
||||
class FiniteStateMachine;
|
||||
class Error;
|
||||
class ShiftCollider;
|
||||
class KernCollider;
|
||||
class json;
|
||||
|
||||
enum passtype;
|
||||
|
||||
class Pass
|
||||
{
|
||||
public:
|
||||
Pass();
|
||||
~Pass();
|
||||
|
||||
bool readPass(const byte * pPass, size_t pass_length, size_t subtable_base, Face & face,
|
||||
enum passtype pt, uint32 version, Error &e);
|
||||
bool runGraphite(vm::Machine & m, FiniteStateMachine & fsm, bool reverse) const;
|
||||
void init(Silf *silf) { m_silf = silf; }
|
||||
byte collisionLoops() const { return m_numCollRuns; }
|
||||
bool reverseDir() const { return m_isReverseDir; }
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
void findNDoRule(Slot* & iSlot, vm::Machine &, FiniteStateMachine& fsm) const;
|
||||
int doAction(const vm::Machine::Code* codeptr, Slot * & slot_out, vm::Machine &) const;
|
||||
bool testPassConstraint(vm::Machine & m) const;
|
||||
bool testConstraint(const Rule & r, vm::Machine &) const;
|
||||
bool readRules(const byte * rule_map, const size_t num_entries,
|
||||
const byte *precontext, const uint16 * sort_key,
|
||||
const uint16 * o_constraint, const byte *constraint_data,
|
||||
const uint16 * o_action, const byte * action_data,
|
||||
Face &, enum passtype pt, Error &e);
|
||||
bool readStates(const byte * starts, const byte * states, const byte * o_rule_map, Face &, Error &e);
|
||||
bool readRanges(const byte * ranges, size_t num_ranges, Error &e);
|
||||
uint16 glyphToCol(const uint16 gid) const;
|
||||
bool runFSM(FiniteStateMachine & fsm, Slot * slot) const;
|
||||
void dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEntry & re) const;
|
||||
void dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * os) const;
|
||||
void adjustSlot(int delta, Slot * & slot_out, SlotMap &) const;
|
||||
bool collisionShift(Segment *seg, int dir, json * const dbgout) const;
|
||||
bool collisionKern(Segment *seg, int dir, json * const dbgout) const;
|
||||
bool collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const;
|
||||
bool resolveCollisions(Segment *seg, Slot *slot, Slot *start, ShiftCollider &coll, bool isRev,
|
||||
int dir, bool &moved, bool &hasCol, json * const dbgout) const;
|
||||
float resolveKern(Segment *seg, Slot *slot, Slot *start, int dir,
|
||||
float &ymin, float &ymax, json *const dbgout) const;
|
||||
|
||||
const Silf * m_silf;
|
||||
uint16 * m_cols;
|
||||
Rule * m_rules; // rules
|
||||
RuleEntry * m_ruleMap;
|
||||
uint16 * m_startStates; // prectxt length
|
||||
uint16 * m_transitions;
|
||||
State * m_states;
|
||||
vm::Machine::Code * m_codes;
|
||||
byte * m_progs;
|
||||
|
||||
byte m_numCollRuns;
|
||||
byte m_kernColls;
|
||||
byte m_iMaxLoop;
|
||||
uint16 m_numGlyphs;
|
||||
uint16 m_numRules;
|
||||
uint16 m_numStates;
|
||||
uint16 m_numTransition;
|
||||
uint16 m_numSuccess;
|
||||
uint16 m_successStart;
|
||||
uint16 m_numColumns;
|
||||
byte m_minPreCtxt;
|
||||
byte m_maxPreCtxt;
|
||||
byte m_colThreshold;
|
||||
bool m_isReverseDir;
|
||||
vm::Machine::Code m_cPConstraint;
|
||||
|
||||
private: //defensive
|
||||
Pass(const Pass&);
|
||||
Pass& operator=(const Pass&);
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
45
thirdparty/graphite/src/inc/Position.h
vendored
Normal file
45
thirdparty/graphite/src/inc/Position.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Position
|
||||
{
|
||||
public:
|
||||
Position() : x(0), y(0) { }
|
||||
Position(const float inx, const float iny) : x(inx), y(iny) {}
|
||||
Position operator + (const Position& a) const { return Position(x + a.x, y + a.y); }
|
||||
Position operator - (const Position& a) const { return Position(x - a.x, y - a.y); }
|
||||
Position operator * (const float m) const { return Position(x * m, y * m); }
|
||||
Position &operator += (const Position &a) { x += a.x; y += a.y; return *this; }
|
||||
Position &operator *= (const float m) { x *= m; y *= m; return *this; }
|
||||
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
class Rect
|
||||
{
|
||||
public :
|
||||
Rect() {}
|
||||
Rect(const Position& botLeft, const Position& topRight): bl(botLeft), tr(topRight) {}
|
||||
Rect widen(const Rect& other) { return Rect(Position(bl.x > other.bl.x ? other.bl.x : bl.x, bl.y > other.bl.y ? other.bl.y : bl.y), Position(tr.x > other.tr.x ? tr.x : other.tr.x, tr.y > other.tr.y ? tr.y : other.tr.y)); }
|
||||
Rect operator + (const Position &a) const { return Rect(Position(bl.x + a.x, bl.y + a.y), Position(tr.x + a.x, tr.y + a.y)); }
|
||||
Rect operator - (const Position &a) const { return Rect(Position(bl.x - a.x, bl.y - a.y), Position(tr.x - a.x, tr.y - a.y)); }
|
||||
Rect operator * (float m) const { return Rect(Position(bl.x, bl.y) * m, Position(tr.x, tr.y) * m); }
|
||||
float width() const { return tr.x - bl.x; }
|
||||
float height() const { return tr.y - bl.y; }
|
||||
|
||||
bool hitTest(Rect &other);
|
||||
|
||||
// returns Position(overlapx, overlapy) where overlap<0 if overlapping else positive)
|
||||
Position overlap(Position &offset, Rect &other, Position &otherOffset);
|
||||
//Position constrainedAvoid(Position &offset, Rect &box, Rect &sdbox, Position &other, Rect &obox, Rect &osdbox);
|
||||
|
||||
Position bl;
|
||||
Position tr;
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
282
thirdparty/graphite/src/inc/Rule.h
vendored
Normal file
282
thirdparty/graphite/src/inc/Rule.h
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2011, SIL International, All rights reserved.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "inc/Code.h"
|
||||
#include "inc/Slot.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
struct Rule {
|
||||
const vm::Machine::Code * constraint,
|
||||
* action;
|
||||
unsigned short sort;
|
||||
byte preContext;
|
||||
#ifndef NDEBUG
|
||||
uint16 rule_idx;
|
||||
#endif
|
||||
|
||||
Rule();
|
||||
~Rule() {}
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
private:
|
||||
Rule(const Rule &);
|
||||
Rule & operator = (const Rule &);
|
||||
};
|
||||
|
||||
inline
|
||||
Rule::Rule()
|
||||
: constraint(0),
|
||||
action(0),
|
||||
sort(0),
|
||||
preContext(0)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
rule_idx = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
struct RuleEntry
|
||||
{
|
||||
const Rule * rule;
|
||||
|
||||
inline
|
||||
bool operator < (const RuleEntry &r) const
|
||||
{
|
||||
const unsigned short lsort = rule->sort, rsort = r.rule->sort;
|
||||
return lsort > rsort || (lsort == rsort && rule < r.rule);
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator == (const RuleEntry &r) const
|
||||
{
|
||||
return rule == r.rule;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct State
|
||||
{
|
||||
const RuleEntry * rules,
|
||||
* rules_end;
|
||||
|
||||
bool empty() const;
|
||||
};
|
||||
|
||||
inline
|
||||
bool State::empty() const
|
||||
{
|
||||
return rules_end == rules;
|
||||
}
|
||||
|
||||
|
||||
class SlotMap
|
||||
{
|
||||
public:
|
||||
enum {MAX_SLOTS=64};
|
||||
SlotMap(Segment & seg, uint8 direction, size_t maxSize);
|
||||
|
||||
Slot * * begin();
|
||||
Slot * * end();
|
||||
size_t size() const;
|
||||
unsigned short context() const;
|
||||
void reset(Slot &, unsigned short);
|
||||
|
||||
Slot * const & operator[](int n) const;
|
||||
Slot * & operator [] (int);
|
||||
void pushSlot(Slot * const slot);
|
||||
void collectGarbage(Slot *& aSlot);
|
||||
|
||||
Slot * highwater() { return m_highwater; }
|
||||
void highwater(Slot *s) { m_highwater = s; m_highpassed = false; }
|
||||
bool highpassed() const { return m_highpassed; }
|
||||
void highpassed(bool v) { m_highpassed = v; }
|
||||
|
||||
uint8 dir() const { return m_dir; }
|
||||
int decMax() { return --m_maxSize; }
|
||||
|
||||
Segment & segment;
|
||||
private:
|
||||
Slot * m_slot_map[MAX_SLOTS+1];
|
||||
unsigned short m_size;
|
||||
unsigned short m_precontext;
|
||||
Slot * m_highwater;
|
||||
int m_maxSize;
|
||||
uint8 m_dir;
|
||||
bool m_highpassed;
|
||||
};
|
||||
|
||||
|
||||
class FiniteStateMachine
|
||||
{
|
||||
public:
|
||||
enum {MAX_RULES=128};
|
||||
|
||||
private:
|
||||
class Rules
|
||||
{
|
||||
public:
|
||||
Rules();
|
||||
void clear();
|
||||
const RuleEntry * begin() const;
|
||||
const RuleEntry * end() const;
|
||||
size_t size() const;
|
||||
|
||||
void accumulate_rules(const State &state);
|
||||
|
||||
private:
|
||||
RuleEntry * m_begin,
|
||||
* m_end,
|
||||
m_rules[MAX_RULES*2];
|
||||
};
|
||||
|
||||
public:
|
||||
FiniteStateMachine(SlotMap & map, json * logger);
|
||||
void reset(Slot * & slot, const short unsigned int max_pre_ctxt);
|
||||
|
||||
Rules rules;
|
||||
SlotMap & slots;
|
||||
json * const dbgout;
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
FiniteStateMachine::FiniteStateMachine(SlotMap& map, json * logger)
|
||||
: slots(map),
|
||||
dbgout(logger)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
void FiniteStateMachine::reset(Slot * & slot, const short unsigned int max_pre_ctxt)
|
||||
{
|
||||
rules.clear();
|
||||
int ctxt = 0;
|
||||
for (; ctxt != max_pre_ctxt && slot->prev(); ++ctxt, slot = slot->prev());
|
||||
slots.reset(*slot, ctxt);
|
||||
}
|
||||
|
||||
inline
|
||||
FiniteStateMachine::Rules::Rules()
|
||||
: m_begin(m_rules), m_end(m_rules)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
void FiniteStateMachine::Rules::clear()
|
||||
{
|
||||
m_end = m_begin;
|
||||
}
|
||||
|
||||
inline
|
||||
const RuleEntry * FiniteStateMachine::Rules::begin() const
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
inline
|
||||
const RuleEntry * FiniteStateMachine::Rules::end() const
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
inline
|
||||
size_t FiniteStateMachine::Rules::size() const
|
||||
{
|
||||
return m_end - m_begin;
|
||||
}
|
||||
|
||||
inline
|
||||
void FiniteStateMachine::Rules::accumulate_rules(const State &state)
|
||||
{
|
||||
// Only bother if there are rules in the State object.
|
||||
if (state.empty()) return;
|
||||
|
||||
// Merge the new sorted rules list into the current sorted result set.
|
||||
const RuleEntry * lre = begin(), * rre = state.rules;
|
||||
RuleEntry * out = m_rules + (m_begin == m_rules)*MAX_RULES;
|
||||
const RuleEntry * const lrend = out + MAX_RULES,
|
||||
* const rrend = state.rules_end;
|
||||
m_begin = out;
|
||||
while (lre != end() && out != lrend)
|
||||
{
|
||||
if (*lre < *rre) *out++ = *lre++;
|
||||
else if (*rre < *lre) { *out++ = *rre++; }
|
||||
else { *out++ = *lre++; ++rre; }
|
||||
|
||||
if (rre == rrend)
|
||||
{
|
||||
while (lre != end() && out != lrend) { *out++ = *lre++; }
|
||||
m_end = out;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (rre != rrend && out != lrend) { *out++ = *rre++; }
|
||||
m_end = out;
|
||||
}
|
||||
|
||||
inline
|
||||
SlotMap::SlotMap(Segment & seg, uint8 direction, size_t maxSize)
|
||||
: segment(seg), m_size(0), m_precontext(0), m_highwater(0),
|
||||
m_maxSize(int(maxSize)), m_dir(direction), m_highpassed(false)
|
||||
{
|
||||
m_slot_map[0] = 0;
|
||||
}
|
||||
|
||||
inline
|
||||
Slot * * SlotMap::begin()
|
||||
{
|
||||
return &m_slot_map[1]; // allow map to go 1 before slot_map when inserting
|
||||
// at start of segment.
|
||||
}
|
||||
|
||||
inline
|
||||
Slot * * SlotMap::end()
|
||||
{
|
||||
return m_slot_map + m_size + 1;
|
||||
}
|
||||
|
||||
inline
|
||||
size_t SlotMap::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline
|
||||
short unsigned int SlotMap::context() const
|
||||
{
|
||||
return m_precontext;
|
||||
}
|
||||
|
||||
inline
|
||||
void SlotMap::reset(Slot & slot, short unsigned int ctxt)
|
||||
{
|
||||
m_size = 0;
|
||||
m_precontext = ctxt;
|
||||
*m_slot_map = slot.prev();
|
||||
}
|
||||
|
||||
inline
|
||||
void SlotMap::pushSlot(Slot*const slot)
|
||||
{
|
||||
m_slot_map[++m_size] = slot;
|
||||
}
|
||||
|
||||
inline
|
||||
Slot * const & SlotMap::operator[](int n) const
|
||||
{
|
||||
return m_slot_map[n + 1];
|
||||
}
|
||||
|
||||
inline
|
||||
Slot * & SlotMap::operator[](int n)
|
||||
{
|
||||
return m_slot_map[n + 1];
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
213
thirdparty/graphite/src/inc/Segment.h
vendored
Normal file
213
thirdparty/graphite/src/inc/Segment.h
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "inc/Main.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "inc/CharInfo.h"
|
||||
#include "inc/Face.h"
|
||||
#include "inc/FeatureVal.h"
|
||||
#include "inc/GlyphCache.h"
|
||||
#include "inc/GlyphFace.h"
|
||||
#include "inc/Slot.h"
|
||||
#include "inc/Position.h"
|
||||
#include "inc/List.h"
|
||||
#include "inc/Collider.h"
|
||||
|
||||
#define MAX_SEG_GROWTH_FACTOR 64
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
typedef Vector<Features> FeatureList;
|
||||
typedef Vector<Slot *> SlotRope;
|
||||
typedef Vector<int16 *> AttributeRope;
|
||||
typedef Vector<SlotJustify *> JustifyRope;
|
||||
|
||||
class Font;
|
||||
class Segment;
|
||||
class Silf;
|
||||
|
||||
enum SpliceParam {
|
||||
/** sub-Segments longer than this are not cached
|
||||
* (in Unicode code points) */
|
||||
eMaxSpliceSize = 96
|
||||
};
|
||||
|
||||
enum justFlags {
|
||||
gr_justStartInline = 1,
|
||||
gr_justEndInline = 2
|
||||
};
|
||||
|
||||
class SegmentScopeState
|
||||
{
|
||||
private:
|
||||
friend class Segment;
|
||||
Slot * realFirstSlot;
|
||||
Slot * slotBeforeScope;
|
||||
Slot * slotAfterScope;
|
||||
Slot * realLastSlot;
|
||||
size_t numGlyphsOutsideScope;
|
||||
};
|
||||
|
||||
class Segment
|
||||
{
|
||||
// Prevent copying of any kind.
|
||||
Segment(const Segment&);
|
||||
Segment& operator=(const Segment&);
|
||||
|
||||
public:
|
||||
|
||||
enum {
|
||||
SEG_INITCOLLISIONS = 1,
|
||||
SEG_HASCOLLISIONS = 2
|
||||
};
|
||||
|
||||
size_t slotCount() const { return m_numGlyphs; } //one slot per glyph
|
||||
void extendLength(ptrdiff_t num) { m_numGlyphs += num; }
|
||||
Position advance() const { return m_advance; }
|
||||
bool runGraphite() { if (m_silf) return m_face->runGraphite(this, m_silf); else return true;};
|
||||
void chooseSilf(uint32 script) { m_silf = m_face->chooseSilf(script); }
|
||||
const Silf *silf() const { return m_silf; }
|
||||
size_t charInfoCount() const { return m_numCharinfo; }
|
||||
const CharInfo *charinfo(unsigned int index) const { return index < m_numCharinfo ? m_charinfo + index : NULL; }
|
||||
CharInfo *charinfo(unsigned int index) { return index < m_numCharinfo ? m_charinfo + index : NULL; }
|
||||
|
||||
Segment(size_t numchars, const Face* face, uint32 script, int dir);
|
||||
~Segment();
|
||||
uint8 flags() const { return m_flags; }
|
||||
void flags(uint8 f) { m_flags = f; }
|
||||
Slot *first() { return m_first; }
|
||||
void first(Slot *p) { m_first = p; }
|
||||
Slot *last() { return m_last; }
|
||||
void last(Slot *p) { m_last = p; }
|
||||
void appendSlot(int i, int cid, int gid, int fid, size_t coffset);
|
||||
Slot *newSlot();
|
||||
void freeSlot(Slot *);
|
||||
SlotJustify *newJustify();
|
||||
void freeJustify(SlotJustify *aJustify);
|
||||
Position positionSlots(const Font *font=0, Slot *first=0, Slot *last=0, bool isRtl = false, bool isFinal = true);
|
||||
void associateChars(int offset, size_t num);
|
||||
void linkClusters(Slot *first, Slot *last);
|
||||
uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); }
|
||||
uint16 findClassIndex(uint16 cid, uint16 gid) const { return m_silf->findClassIndex(cid, gid); }
|
||||
int addFeatures(const Features& feats) { m_feats.push_back(feats); return int(m_feats.size()) - 1; }
|
||||
uint32 getFeature(int index, uint8 findex) const { const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex); if (!pFR) return 0; else return pFR->getFeatureVal(m_feats[index]); }
|
||||
void setFeature(int index, uint8 findex, uint32 val) {
|
||||
const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex);
|
||||
if (pFR)
|
||||
{
|
||||
if (val > pFR->maxVal()) val = pFR->maxVal();
|
||||
pFR->applyValToFeature(val, m_feats[index]);
|
||||
} }
|
||||
int8 dir() const { return m_dir; }
|
||||
void dir(int8 val) { m_dir = val; }
|
||||
bool currdir() const { return ((m_dir >> 6) ^ m_dir) & 1; }
|
||||
uint8 passBits() const { return m_passBits; }
|
||||
void mergePassBits(const uint8 val) { m_passBits &= val; }
|
||||
int16 glyphAttr(uint16 gid, uint16 gattr) const { const GlyphFace * p = m_face->glyphs().glyphSafe(gid); return p ? p->attrs()[gattr] : 0; }
|
||||
int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel, bool rtl) const;
|
||||
float glyphAdvance(uint16 gid) const { return m_face->glyphs().glyph(gid)->theAdvance().x; }
|
||||
const Rect &theGlyphBBoxTemporary(uint16 gid) const { return m_face->glyphs().glyph(gid)->theBBox(); } //warning value may become invalid when another glyph is accessed
|
||||
Slot *findRoot(Slot *is) const { return is->attachedTo() ? findRoot(is->attachedTo()) : is; }
|
||||
int numAttrs() const { return m_silf->numUser(); }
|
||||
int defaultOriginal() const { return m_defaultOriginal; }
|
||||
const Face * getFace() const { return m_face; }
|
||||
const Features & getFeatures(unsigned int /*charIndex*/) { assert(m_feats.size() == 1); return m_feats[0]; }
|
||||
void bidiPass(int paradir, uint8 aMirror);
|
||||
int8 getSlotBidiClass(Slot *s) const;
|
||||
void doMirror(uint16 aMirror);
|
||||
Slot *addLineEnd(Slot *nSlot);
|
||||
void delLineEnd(Slot *s);
|
||||
bool hasJustification() const { return m_justifies.size() != 0; }
|
||||
void reverseSlots();
|
||||
|
||||
bool isWhitespace(const int cid) const;
|
||||
bool hasCollisionInfo() const { return (m_flags & SEG_HASCOLLISIONS) && m_collisions; }
|
||||
SlotCollision *collisionInfo(const Slot *s) const { return m_collisions ? m_collisions + s->index() : 0; }
|
||||
CLASS_NEW_DELETE
|
||||
|
||||
public: //only used by: GrSegment* makeAndInitialize(const GrFont *font, const GrFace *face, uint32 script, const FeaturesHandle& pFeats/*must not be IsNull*/, encform enc, const void* pStart, size_t nChars, int dir);
|
||||
bool read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void*pStart, size_t nChars);
|
||||
void finalise(const Font *font, bool reverse=false);
|
||||
float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
|
||||
bool initCollisions();
|
||||
|
||||
private:
|
||||
Position m_advance; // whole segment advance
|
||||
SlotRope m_slots; // Vector of slot buffers
|
||||
AttributeRope m_userAttrs; // Vector of userAttrs buffers
|
||||
JustifyRope m_justifies; // Slot justification info buffers
|
||||
FeatureList m_feats; // feature settings referenced by charinfos in this segment
|
||||
Slot * m_freeSlots; // linked list of free slots
|
||||
SlotJustify * m_freeJustifies; // Slot justification blocks free list
|
||||
CharInfo * m_charinfo; // character info, one per input character
|
||||
SlotCollision * m_collisions;
|
||||
const Face * m_face; // GrFace
|
||||
const Silf * m_silf;
|
||||
Slot * m_first; // first slot in segment
|
||||
Slot * m_last; // last slot in segment
|
||||
size_t m_bufSize, // how big a buffer to create when need more slots
|
||||
m_numGlyphs,
|
||||
m_numCharinfo; // size of the array and number of input characters
|
||||
int m_defaultOriginal; // number of whitespace chars in the string
|
||||
int8 m_dir;
|
||||
uint8 m_flags, // General purpose flags
|
||||
m_passBits; // if bit set then skip pass
|
||||
};
|
||||
|
||||
inline
|
||||
int8 Segment::getSlotBidiClass(Slot *s) const
|
||||
{
|
||||
int8 res = s->getBidiClass();
|
||||
if (res != -1) return res;
|
||||
res = int8(glyphAttr(s->gid(), m_silf->aBidi()));
|
||||
s->setBidiClass(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline
|
||||
void Segment::finalise(const Font *font, bool reverse)
|
||||
{
|
||||
if (!m_first || !m_last) return;
|
||||
|
||||
m_advance = positionSlots(font, m_first, m_last, m_silf->dir(), true);
|
||||
//associateChars(0, m_numCharinfo);
|
||||
if (reverse && currdir() != (m_dir & 1))
|
||||
reverseSlots();
|
||||
linkClusters(m_first, m_last);
|
||||
}
|
||||
|
||||
inline
|
||||
int32 Segment::getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel, bool rtl) const {
|
||||
if (attrLevel > 0)
|
||||
{
|
||||
Slot *is = findRoot(iSlot);
|
||||
return is->clusterMetric(this, metric, attrLevel, rtl);
|
||||
}
|
||||
else
|
||||
return m_face->getGlyphMetric(iSlot->gid(), metric);
|
||||
}
|
||||
|
||||
inline
|
||||
bool Segment::isWhitespace(const int cid) const
|
||||
{
|
||||
return ((cid >= 0x0009) * (cid <= 0x000D)
|
||||
+ (cid == 0x0020)
|
||||
+ (cid == 0x0085)
|
||||
+ (cid == 0x00A0)
|
||||
+ (cid == 0x1680)
|
||||
+ (cid == 0x180E)
|
||||
+ (cid >= 0x2000) * (cid <= 0x200A)
|
||||
+ (cid == 0x2028)
|
||||
+ (cid == 0x2029)
|
||||
+ (cid == 0x202F)
|
||||
+ (cid == 0x205F)
|
||||
+ (cid == 0x3000)) != 0;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
struct gr_segment : public graphite2::Segment {};
|
105
thirdparty/graphite/src/inc/Silf.h
vendored
Normal file
105
thirdparty/graphite/src/inc/Silf.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphite2/Font.h"
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Pass.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Face;
|
||||
class Segment;
|
||||
class FeatureVal;
|
||||
class VMScratch;
|
||||
class Error;
|
||||
|
||||
class Pseudo
|
||||
{
|
||||
public:
|
||||
uint32 uid;
|
||||
uint32 gid;
|
||||
CLASS_NEW_DELETE;
|
||||
};
|
||||
|
||||
class Justinfo
|
||||
{
|
||||
public:
|
||||
Justinfo(uint8 stretch, uint8 shrink, uint8 step, uint8 weight) :
|
||||
m_astretch(stretch), m_ashrink(shrink), m_astep(step),
|
||||
m_aweight(weight) {};
|
||||
uint8 attrStretch() const { return m_astretch; }
|
||||
uint8 attrShrink() const { return m_ashrink; }
|
||||
uint8 attrStep() const { return m_astep; }
|
||||
uint8 attrWeight() const { return m_aweight; }
|
||||
|
||||
private:
|
||||
uint8 m_astretch;
|
||||
uint8 m_ashrink;
|
||||
uint8 m_astep;
|
||||
uint8 m_aweight;
|
||||
};
|
||||
|
||||
class Silf
|
||||
{
|
||||
// Prevent copying
|
||||
Silf(const Silf&);
|
||||
Silf& operator=(const Silf&);
|
||||
|
||||
public:
|
||||
Silf() throw();
|
||||
~Silf() throw();
|
||||
|
||||
bool readGraphite(const byte * const pSilf, size_t lSilf, Face &face, uint32 version);
|
||||
bool runGraphite(Segment *seg, uint8 firstPass=0, uint8 lastPass=0, int dobidi = 0) const;
|
||||
uint16 findClassIndex(uint16 cid, uint16 gid) const;
|
||||
uint16 getClassGlyph(uint16 cid, unsigned int index) const;
|
||||
uint16 findPseudo(uint32 uid) const;
|
||||
uint8 numUser() const { return m_aUser; }
|
||||
uint8 aPseudo() const { return m_aPseudo; }
|
||||
uint8 aBreak() const { return m_aBreak; }
|
||||
uint8 aMirror() const {return m_aMirror; }
|
||||
uint8 aPassBits() const { return m_aPassBits; }
|
||||
uint8 aBidi() const { return m_aBidi; }
|
||||
uint8 aCollision() const { return m_aCollision; }
|
||||
uint8 substitutionPass() const { return m_sPass; }
|
||||
uint8 positionPass() const { return m_pPass; }
|
||||
uint8 justificationPass() const { return m_jPass; }
|
||||
uint8 bidiPass() const { return m_bPass; }
|
||||
uint8 numPasses() const { return m_numPasses; }
|
||||
uint8 maxCompPerLig() const { return m_iMaxComp; }
|
||||
uint16 numClasses() const { return m_nClass; }
|
||||
byte flags() const { return m_flags; }
|
||||
byte dir() const { return m_dir; }
|
||||
uint8 numJustLevels() const { return m_numJusts; }
|
||||
Justinfo *justAttrs() const { return m_justs; }
|
||||
uint16 endLineGlyphid() const { return m_gEndLine; }
|
||||
const gr_faceinfo *silfInfo() const { return &m_silfinfo; }
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
private:
|
||||
size_t readClassMap(const byte *p, size_t data_len, uint32 version, Error &e);
|
||||
template<typename T> inline uint32 readClassOffsets(const byte *&p, size_t data_len, Error &e);
|
||||
|
||||
Pass * m_passes;
|
||||
Pseudo * m_pseudos;
|
||||
uint32 * m_classOffsets;
|
||||
uint16 * m_classData;
|
||||
Justinfo * m_justs;
|
||||
uint8 m_numPasses;
|
||||
uint8 m_numJusts;
|
||||
uint8 m_sPass, m_pPass, m_jPass, m_bPass,
|
||||
m_flags, m_dir;
|
||||
|
||||
uint8 m_aPseudo, m_aBreak, m_aUser, m_aBidi, m_aMirror, m_aPassBits,
|
||||
m_iMaxComp, m_aCollision;
|
||||
uint16 m_aLig, m_numPseudo, m_nClass, m_nLinear,
|
||||
m_gEndLine;
|
||||
gr_faceinfo m_silfinfo;
|
||||
|
||||
void releaseBuffers() throw();
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
147
thirdparty/graphite/src/inc/Slot.h
vendored
Normal file
147
thirdparty/graphite/src/inc/Slot.h
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphite2/Types.h"
|
||||
#include "graphite2/Segment.h"
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Font.h"
|
||||
#include "inc/Position.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
typedef gr_attrCode attrCode;
|
||||
|
||||
class GlyphFace;
|
||||
class Segment;
|
||||
|
||||
struct SlotJustify
|
||||
{
|
||||
static const int NUMJUSTPARAMS = 5;
|
||||
|
||||
SlotJustify(const SlotJustify &);
|
||||
SlotJustify & operator = (const SlotJustify &);
|
||||
|
||||
public:
|
||||
static size_t size_of(size_t levels) { return sizeof(SlotJustify) + ((levels > 1 ? levels : 1)*NUMJUSTPARAMS - 1)*sizeof(int16); }
|
||||
|
||||
void LoadSlot(const Slot *s, const Segment *seg);
|
||||
|
||||
SlotJustify *next;
|
||||
int16 values[1];
|
||||
};
|
||||
|
||||
class Slot
|
||||
{
|
||||
enum Flag
|
||||
{
|
||||
DELETED = 1,
|
||||
INSERTED = 2,
|
||||
COPIED = 4,
|
||||
POSITIONED = 8,
|
||||
ATTACHED = 16
|
||||
};
|
||||
|
||||
public:
|
||||
struct iterator;
|
||||
|
||||
unsigned short gid() const { return m_glyphid; }
|
||||
Position origin() const { return m_position; }
|
||||
float advance() const { return m_advance.x; }
|
||||
void advance(Position &val) { m_advance = val; }
|
||||
Position advancePos() const { return m_advance; }
|
||||
int before() const { return m_before; }
|
||||
int after() const { return m_after; }
|
||||
uint32 index() const { return m_index; }
|
||||
void index(uint32 val) { m_index = val; }
|
||||
|
||||
Slot(int16 *m_userAttr = NULL);
|
||||
void set(const Slot & slot, int charOffset, size_t numUserAttr, size_t justLevels, size_t numChars);
|
||||
Slot *next() const { return m_next; }
|
||||
void next(Slot *s) { m_next = s; }
|
||||
Slot *prev() const { return m_prev; }
|
||||
void prev(Slot *s) { m_prev = s; }
|
||||
uint16 glyph() const { return m_realglyphid ? m_realglyphid : m_glyphid; }
|
||||
void setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph = NULL);
|
||||
void setRealGid(uint16 realGid) { m_realglyphid = realGid; }
|
||||
void adjKern(const Position &pos) { m_shift = m_shift + pos; m_advance = m_advance + pos; }
|
||||
void origin(const Position &pos) { m_position = pos + m_shift; }
|
||||
void originate(int ind) { m_original = ind; }
|
||||
int original() const { return m_original; }
|
||||
void before(int ind) { m_before = ind; }
|
||||
void after(int ind) { m_after = ind; }
|
||||
bool isBase() const { return (!m_parent); }
|
||||
void update(int numSlots, int numCharInfo, Position &relpos);
|
||||
Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal, int depth = 0);
|
||||
bool isDeleted() const { return (m_flags & DELETED) ? true : false; }
|
||||
void markDeleted(bool state) { if (state) m_flags |= DELETED; else m_flags &= ~DELETED; }
|
||||
bool isCopied() const { return (m_flags & COPIED) ? true : false; }
|
||||
void markCopied(bool state) { if (state) m_flags |= COPIED; else m_flags &= ~COPIED; }
|
||||
bool isPositioned() const { return (m_flags & POSITIONED) ? true : false; }
|
||||
void markPositioned(bool state) { if (state) m_flags |= POSITIONED; else m_flags &= ~POSITIONED; }
|
||||
bool isInsertBefore() const { return !(m_flags & INSERTED); }
|
||||
uint8 getBidiLevel() const { return m_bidiLevel; }
|
||||
void setBidiLevel(uint8 level) { m_bidiLevel = level; }
|
||||
int8 getBidiClass(const Segment *seg);
|
||||
int8 getBidiClass() const { return m_bidiCls; }
|
||||
void setBidiClass(int8 cls) { m_bidiCls = cls; }
|
||||
int16 *userAttrs() const { return m_userAttr; }
|
||||
void userAttrs(int16 *p) { m_userAttr = p; }
|
||||
void markInsertBefore(bool state) { if (!state) m_flags |= INSERTED; else m_flags &= ~INSERTED; }
|
||||
void setAttr(Segment* seg, attrCode ind, uint8 subindex, int16 val, const SlotMap & map);
|
||||
int getAttr(const Segment *seg, attrCode ind, uint8 subindex) const;
|
||||
int getJustify(const Segment *seg, uint8 level, uint8 subindex) const;
|
||||
void setJustify(Segment *seg, uint8 level, uint8 subindex, int16 value);
|
||||
bool isLocalJustify() const { return m_justs != NULL; };
|
||||
void attachTo(Slot *ap) { m_parent = ap; }
|
||||
Slot *attachedTo() const { return m_parent; }
|
||||
Position attachOffset() const { return m_attach - m_with; }
|
||||
Slot* firstChild() const { return m_child; }
|
||||
void firstChild(Slot *ap) { m_child = ap; }
|
||||
bool child(Slot *ap);
|
||||
Slot* nextSibling() const { return m_sibling; }
|
||||
void nextSibling(Slot *ap) { m_sibling = ap; }
|
||||
bool sibling(Slot *ap);
|
||||
bool removeChild(Slot *ap);
|
||||
int32 clusterMetric(const Segment* seg, uint8 metric, uint8 attrLevel, bool rtl);
|
||||
void positionShift(Position a) { m_position += a; }
|
||||
void floodShift(Position adj, int depth = 0);
|
||||
float just() const { return m_just; }
|
||||
void just(float j) { m_just = j; }
|
||||
Slot *nextInCluster(const Slot *s) const;
|
||||
bool isChildOf(const Slot *base) const;
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
|
||||
private:
|
||||
Slot *m_next; // linked list of slots
|
||||
Slot *m_prev;
|
||||
unsigned short m_glyphid; // glyph id
|
||||
uint16 m_realglyphid;
|
||||
uint32 m_original; // charinfo that originated this slot (e.g. for feature values)
|
||||
uint32 m_before; // charinfo index of before association
|
||||
uint32 m_after; // charinfo index of after association
|
||||
uint32 m_index; // slot index given to this slot during finalising
|
||||
Slot *m_parent; // index to parent we are attached to
|
||||
Slot *m_child; // index to first child slot that attaches to us
|
||||
Slot *m_sibling; // index to next child that attaches to our parent
|
||||
Position m_position; // absolute position of glyph
|
||||
Position m_shift; // .shift slot attribute
|
||||
Position m_advance; // .advance slot attribute
|
||||
Position m_attach; // attachment point on us
|
||||
Position m_with; // attachment point position on parent
|
||||
float m_just; // Justification inserted space
|
||||
uint8 m_flags; // holds bit flags
|
||||
byte m_attLevel; // attachment level
|
||||
int8 m_bidiCls; // bidirectional class
|
||||
byte m_bidiLevel; // bidirectional level
|
||||
int16 *m_userAttr; // pointer to user attributes
|
||||
SlotJustify *m_justs; // pointer to justification parameters
|
||||
|
||||
friend class Segment;
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
struct gr_slot : public graphite2::Slot {};
|
145
thirdparty/graphite/src/inc/Sparse.h
vendored
Normal file
145
thirdparty/graphite/src/inc/Sparse.h
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2011, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
#include "inc/Main.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
|
||||
// A read-only packed fast sparse array of uint16 with uint16 keys.
|
||||
// Like most container classes this has capacity and size properties and these
|
||||
// refer to the number of stored entries and the number of addressable entries
|
||||
// as normal. However due the sparse nature the capacity is always <= than the
|
||||
// size.
|
||||
class sparse
|
||||
{
|
||||
public:
|
||||
typedef uint16 key_type;
|
||||
typedef uint16 mapped_type;
|
||||
typedef std::pair<const key_type, mapped_type> value_type;
|
||||
|
||||
private:
|
||||
typedef unsigned long mask_t;
|
||||
|
||||
static const unsigned char SIZEOF_CHUNK = (sizeof(mask_t) - sizeof(key_type))*8;
|
||||
|
||||
struct chunk
|
||||
{
|
||||
mask_t mask:SIZEOF_CHUNK;
|
||||
key_type offset;
|
||||
};
|
||||
|
||||
static const chunk empty_chunk;
|
||||
sparse(const sparse &);
|
||||
sparse & operator = (const sparse &);
|
||||
|
||||
public:
|
||||
template<typename I>
|
||||
sparse(I first, const I last);
|
||||
sparse() throw();
|
||||
~sparse() throw();
|
||||
|
||||
operator bool () const throw();
|
||||
mapped_type operator [] (const key_type k) const throw();
|
||||
|
||||
size_t capacity() const throw();
|
||||
size_t size() const throw();
|
||||
|
||||
size_t _sizeof() const throw();
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
private:
|
||||
union {
|
||||
chunk * map;
|
||||
mapped_type * values;
|
||||
} m_array;
|
||||
key_type m_nchunks;
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
sparse::sparse() throw() : m_nchunks(0)
|
||||
{
|
||||
m_array.map = const_cast<graphite2::sparse::chunk *>(&empty_chunk);
|
||||
}
|
||||
|
||||
|
||||
template <typename I>
|
||||
sparse::sparse(I attr, const I last)
|
||||
: m_nchunks(0)
|
||||
{
|
||||
m_array.map = 0;
|
||||
|
||||
// Find the maximum extent of the key space.
|
||||
size_t n_values=0;
|
||||
long lastkey = -1;
|
||||
for (I i = attr; i != last; ++i, ++n_values)
|
||||
{
|
||||
const typename std::iterator_traits<I>::value_type v = *i;
|
||||
if (v.second == 0) { --n_values; continue; }
|
||||
if (v.first <= lastkey) { m_nchunks = 0; return; }
|
||||
|
||||
lastkey = v.first;
|
||||
const key_type k = v.first / SIZEOF_CHUNK;
|
||||
if (k >= m_nchunks) m_nchunks = k+1;
|
||||
}
|
||||
if (m_nchunks == 0)
|
||||
{
|
||||
m_array.map=const_cast<graphite2::sparse::chunk *>(&empty_chunk);
|
||||
return;
|
||||
}
|
||||
|
||||
m_array.values = grzeroalloc<mapped_type>((m_nchunks*sizeof(chunk) + sizeof(mapped_type)-1)
|
||||
/ sizeof(mapped_type)
|
||||
+ n_values);
|
||||
|
||||
if (m_array.values == 0)
|
||||
return;
|
||||
|
||||
// coverity[forward_null : FALSE] Since m_array is union and m_array.values is not NULL
|
||||
chunk * ci = m_array.map;
|
||||
ci->offset = (m_nchunks*sizeof(chunk) + sizeof(mapped_type)-1)/sizeof(mapped_type);
|
||||
mapped_type * vi = m_array.values + ci->offset;
|
||||
for (; attr != last; ++attr, ++vi)
|
||||
{
|
||||
const typename std::iterator_traits<I>::value_type v = *attr;
|
||||
if (v.second == 0) { --vi; continue; }
|
||||
|
||||
chunk * const ci_ = m_array.map + v.first/SIZEOF_CHUNK;
|
||||
|
||||
if (ci != ci_)
|
||||
{
|
||||
ci = ci_;
|
||||
ci->offset = key_type(vi - m_array.values);
|
||||
}
|
||||
|
||||
ci->mask |= 1UL << (SIZEOF_CHUNK - 1 - (v.first % SIZEOF_CHUNK));
|
||||
*vi = v.second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
sparse::operator bool () const throw()
|
||||
{
|
||||
return m_array.map != 0;
|
||||
}
|
||||
|
||||
inline
|
||||
size_t sparse::size() const throw()
|
||||
{
|
||||
return m_nchunks*SIZEOF_CHUNK;
|
||||
}
|
||||
|
||||
inline
|
||||
size_t sparse::_sizeof() const throw()
|
||||
{
|
||||
return sizeof(sparse) + capacity()*sizeof(mapped_type) + m_nchunks*sizeof(chunk);
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
394
thirdparty/graphite/src/inc/TtfTypes.h
vendored
Normal file
394
thirdparty/graphite/src/inc/TtfTypes.h
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
/*
|
||||
Responsibility: Tim Eves
|
||||
Last reviewed: Not yet.
|
||||
|
||||
Description:
|
||||
Provides types required to represent the TTF basic types.
|
||||
*/
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// Include files
|
||||
//**********************************************************************************************
|
||||
namespace graphite2
|
||||
{
|
||||
namespace TtfUtil
|
||||
{
|
||||
//**********************************************************************************************
|
||||
// Forward declarations
|
||||
//**********************************************************************************************
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// Type declarations
|
||||
//**********************************************************************************************
|
||||
typedef unsigned char uint8;
|
||||
typedef uint8 byte;
|
||||
typedef signed char int8;
|
||||
typedef unsigned short uint16;
|
||||
typedef short int16;
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32;
|
||||
|
||||
typedef int16 short_frac;
|
||||
typedef int32 fixed;
|
||||
typedef int16 fword;
|
||||
typedef uint16 ufword;
|
||||
typedef int16 f2dot14;
|
||||
typedef uint32 long_date_time[2];
|
||||
|
||||
//**********************************************************************************************
|
||||
// Constants and enum types
|
||||
//**********************************************************************************************/
|
||||
enum
|
||||
{
|
||||
OneFix = 1<<16
|
||||
};
|
||||
|
||||
//**********************************************************************************************
|
||||
// Table declarations
|
||||
//**********************************************************************************************
|
||||
namespace Sfnt
|
||||
{
|
||||
#pragma pack(push,1) // We need this or the structure members aren't aligned
|
||||
// correctly. Fortunately this form of pragma is supposed
|
||||
// to be recognised by VS C++ too (at least according to
|
||||
// MSDN).
|
||||
|
||||
struct OffsetSubTable
|
||||
{
|
||||
uint32 scaler_type;
|
||||
uint16 num_tables,
|
||||
search_range,
|
||||
entry_selector,
|
||||
range_shift;
|
||||
struct Entry
|
||||
{
|
||||
uint32 tag,
|
||||
checksum,
|
||||
offset,
|
||||
length;
|
||||
} table_directory[1];
|
||||
|
||||
enum ScalerType
|
||||
{
|
||||
TrueTypeMac = 0x74727565U,
|
||||
TrueTypeWin = 0x00010000U,
|
||||
Type1 = 0x74797031U
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct CharacterCodeMap
|
||||
{
|
||||
uint16 version,
|
||||
num_subtables;
|
||||
struct
|
||||
{
|
||||
uint16 platform_id,
|
||||
platform_specific_id;
|
||||
uint32 offset;
|
||||
} encoding[1];
|
||||
};
|
||||
|
||||
struct CmapSubTable
|
||||
{
|
||||
uint16 format,
|
||||
length,
|
||||
language;
|
||||
};
|
||||
|
||||
struct CmapSubTableFormat4 : CmapSubTable
|
||||
{
|
||||
uint16 seg_count_x2,
|
||||
search_range,
|
||||
entry_selector,
|
||||
range_shift,
|
||||
end_code[1];
|
||||
// There are arrarys after this which need their
|
||||
// start positions calculated since end_code is
|
||||
// seg_count uint16s long.
|
||||
};
|
||||
|
||||
struct CmapSubTableFormat12
|
||||
{
|
||||
fixed format;
|
||||
uint32 length,
|
||||
language,
|
||||
num_groups;
|
||||
struct
|
||||
{
|
||||
uint32 start_char_code,
|
||||
end_char_code,
|
||||
start_glyph_id;
|
||||
} group[1];
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct FontHeader
|
||||
{
|
||||
fixed version,
|
||||
font_revision;
|
||||
uint32 check_sum_adjustment,
|
||||
magic_number;
|
||||
uint16 flags,
|
||||
units_per_em;
|
||||
long_date_time created,
|
||||
modified;
|
||||
fword x_min,
|
||||
y_min,
|
||||
x_max,
|
||||
y_max;
|
||||
uint16 mac_style,
|
||||
lowest_rec_ppem;
|
||||
int16 font_direction_hint,
|
||||
index_to_loc_format,
|
||||
glyph_data_format;
|
||||
enum
|
||||
{
|
||||
MagicNumber = 0x5F0F3CF5,
|
||||
GlypDataFormat = 0
|
||||
};
|
||||
enum {ShortIndexLocFormat, LongIndexLocFormat};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct PostScriptGlyphName
|
||||
{
|
||||
fixed format,
|
||||
italic_angle;
|
||||
fword underline_position,
|
||||
underline_thickness;
|
||||
uint32 is_fixed_pitch,
|
||||
min_mem_type42,
|
||||
max_mem_type42,
|
||||
min_mem_type1,
|
||||
max_mem_type1;
|
||||
enum
|
||||
{
|
||||
Format1 = 0x10000,
|
||||
Format2 = 0x20000,
|
||||
Format25 = 0x28000,
|
||||
Format3 = 0x30000,
|
||||
Format4 = 0x40000
|
||||
};
|
||||
};
|
||||
|
||||
struct PostScriptGlyphName2 : PostScriptGlyphName
|
||||
{
|
||||
uint16 number_of_glyphs,
|
||||
glyph_name_index[1];
|
||||
};
|
||||
|
||||
struct PostScriptGlyphName25 : PostScriptGlyphName
|
||||
{
|
||||
uint16 number_of_glyphs;
|
||||
int8 offset[1];
|
||||
};
|
||||
|
||||
struct PostScriptGlyphName3 : PostScriptGlyphName {};
|
||||
|
||||
struct PostScriptGlyphName4 : PostScriptGlyphName
|
||||
{
|
||||
uint16 glyph_to_char_map[1];
|
||||
};
|
||||
|
||||
|
||||
struct HorizontalHeader
|
||||
{
|
||||
fixed version;
|
||||
fword ascent,
|
||||
descent,
|
||||
line_gap;
|
||||
ufword advance_width_max;
|
||||
fword min_left_side_bearing,
|
||||
max_left_side_bearing,
|
||||
x_max_element;
|
||||
int16 caret_slope_rise,
|
||||
caret_slope_run;
|
||||
fword caret_offset;
|
||||
int16 reserved[4],
|
||||
metric_data_format;
|
||||
uint16 num_long_hor_metrics;
|
||||
};
|
||||
|
||||
struct MaximumProfile
|
||||
{
|
||||
fixed version;
|
||||
uint16 num_glyphs,
|
||||
max_points,
|
||||
max_contours,
|
||||
max_component_points,
|
||||
max_component_contours,
|
||||
max_zones,
|
||||
max_twilight_points,
|
||||
max_storage,
|
||||
max_function_defs,
|
||||
max_instruction_defs,
|
||||
max_stack_elements,
|
||||
max_size_of_instructions,
|
||||
max_component_elements,
|
||||
max_component_depth;
|
||||
};
|
||||
|
||||
|
||||
typedef byte Panose[10];
|
||||
|
||||
struct Compatibility0
|
||||
{
|
||||
uint16 version;
|
||||
int16 x_avg_char_width;
|
||||
uint16 weight_class,
|
||||
width_class;
|
||||
int16 fs_type,
|
||||
y_subscript_x_size,
|
||||
y_subscript_y_size,
|
||||
y_subscript_x_offset,
|
||||
y_subscript_y_offset,
|
||||
y_superscript_x_size,
|
||||
y_superscript_y_size,
|
||||
y_superscript_x_offset,
|
||||
y_superscript_y_offset,
|
||||
y_strikeout_size,
|
||||
y_strikeout_position,
|
||||
family_class;
|
||||
Panose panose;
|
||||
uint32 unicode_range[4];
|
||||
int8 ach_vend_id[4];
|
||||
uint16 fs_selection,
|
||||
fs_first_char_index,
|
||||
fs_last_char_index, // Acording to Apple's spec this is where v0 should end
|
||||
typo_ascender,
|
||||
typo_descender,
|
||||
type_linegap,
|
||||
win_ascent,
|
||||
win_descent;
|
||||
|
||||
enum
|
||||
{
|
||||
Italic =0x01,
|
||||
Underscore=0x02,
|
||||
Negative =0x04,
|
||||
Outlined =0x08,
|
||||
StrikeOut =0x10,
|
||||
Bold =0x20
|
||||
};
|
||||
};
|
||||
|
||||
struct Compatibility1 : Compatibility0
|
||||
{
|
||||
uint32 codepage_range[2];
|
||||
};
|
||||
|
||||
struct Compatibility2 : Compatibility1
|
||||
{
|
||||
int16 x_height,
|
||||
cap_height;
|
||||
uint16 default_char,
|
||||
break_char,
|
||||
max_context;
|
||||
};
|
||||
|
||||
struct Compatibility3 : Compatibility2 {};
|
||||
|
||||
typedef Compatibility3 Compatibility;
|
||||
|
||||
|
||||
struct NameRecord
|
||||
{
|
||||
uint16 platform_id,
|
||||
platform_specific_id,
|
||||
language_id,
|
||||
name_id,
|
||||
length,
|
||||
offset;
|
||||
enum {Unicode, Mactintosh, Reserved, Microsoft};
|
||||
enum
|
||||
{
|
||||
Copyright, Family, Subfamily, UniqueSubfamily,
|
||||
Fullname, Version, PostScript
|
||||
};
|
||||
};
|
||||
|
||||
struct LangTagRecord
|
||||
{
|
||||
uint16 length,
|
||||
offset;
|
||||
};
|
||||
|
||||
struct FontNames
|
||||
{
|
||||
uint16 format,
|
||||
count,
|
||||
string_offset;
|
||||
NameRecord name_record[1];
|
||||
};
|
||||
|
||||
|
||||
struct HorizontalMetric
|
||||
{
|
||||
uint16 advance_width;
|
||||
int16 left_side_bearing;
|
||||
};
|
||||
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
int16 number_of_contours;
|
||||
fword x_min,
|
||||
y_min,
|
||||
x_max,
|
||||
y_max;
|
||||
};
|
||||
|
||||
struct SimpleGlyph : Glyph
|
||||
{
|
||||
uint16 end_pts_of_contours[1];
|
||||
enum
|
||||
{
|
||||
OnCurve = 0x01,
|
||||
XShort = 0x02,
|
||||
YShort = 0x04,
|
||||
Repeat = 0x08,
|
||||
XIsSame = 0x10,
|
||||
XIsPos = 0x10,
|
||||
YIsSame = 0x20,
|
||||
YIsPos = 0x20
|
||||
};
|
||||
};
|
||||
|
||||
struct CompoundGlyph : Glyph
|
||||
{
|
||||
uint16 flags,
|
||||
glyph_index;
|
||||
enum
|
||||
{
|
||||
Arg1Arg2Words = 0x01,
|
||||
ArgsAreXYValues = 0x02,
|
||||
RoundXYToGrid = 0x04,
|
||||
HaveScale = 0x08,
|
||||
MoreComponents = 0x20,
|
||||
HaveXAndYScale = 0x40,
|
||||
HaveTwoByTwo = 0x80,
|
||||
HaveInstructions = 0x100,
|
||||
UseMyMetrics = 0x200,
|
||||
OverlapCompund = 0x400,
|
||||
ScaledOffset = 0x800,
|
||||
UnscaledOffset = 0x1000
|
||||
};
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
} // end of namespace Sfnt
|
||||
|
||||
} // end of namespace TtfUtil
|
||||
} // end of namespace graphite2
|
182
thirdparty/graphite/src/inc/TtfUtil.h
vendored
Normal file
182
thirdparty/graphite/src/inc/TtfUtil.h
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
/*
|
||||
Responsibility: Alan Ward
|
||||
Last reviewed: Not yet.
|
||||
|
||||
Description:
|
||||
Utility class for handling TrueType font files.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace graphite2
|
||||
{
|
||||
namespace TtfUtil
|
||||
{
|
||||
|
||||
#define OVERFLOW_OFFSET_CHECK(p, o) (o + reinterpret_cast<size_t>(p) < reinterpret_cast<size_t>(p))
|
||||
|
||||
typedef long fontTableId32;
|
||||
typedef unsigned short gid16;
|
||||
|
||||
#define TTF_TAG(a,b,c,d) ((a << 24UL) + (b << 16UL) + (c << 8UL) + (d))
|
||||
|
||||
// Enumeration used to specify a table in a TTF file
|
||||
class Tag
|
||||
{
|
||||
unsigned int _v;
|
||||
public:
|
||||
Tag(const char n[5]) throw() : _v(TTF_TAG(n[0],n[1],n[2],n[3])) {}
|
||||
Tag(const unsigned int tag) throw() : _v(tag) {}
|
||||
|
||||
operator unsigned int () const throw () { return _v; }
|
||||
|
||||
enum
|
||||
{
|
||||
Feat = TTF_TAG('F','e','a','t'),
|
||||
Glat = TTF_TAG('G','l','a','t'),
|
||||
Gloc = TTF_TAG('G','l','o','c'),
|
||||
Sile = TTF_TAG('S','i','l','e'),
|
||||
Silf = TTF_TAG('S','i','l','f'),
|
||||
Sill = TTF_TAG('S','i','l','l'),
|
||||
cmap = TTF_TAG('c','m','a','p'),
|
||||
cvt = TTF_TAG('c','v','t',' '),
|
||||
cryp = TTF_TAG('c','r','y','p'),
|
||||
head = TTF_TAG('h','e','a','d'),
|
||||
fpgm = TTF_TAG('f','p','g','m'),
|
||||
gdir = TTF_TAG('g','d','i','r'),
|
||||
glyf = TTF_TAG('g','l','y','f'),
|
||||
hdmx = TTF_TAG('h','d','m','x'),
|
||||
hhea = TTF_TAG('h','h','e','a'),
|
||||
hmtx = TTF_TAG('h','m','t','x'),
|
||||
loca = TTF_TAG('l','o','c','a'),
|
||||
kern = TTF_TAG('k','e','r','n'),
|
||||
LTSH = TTF_TAG('L','T','S','H'),
|
||||
maxp = TTF_TAG('m','a','x','p'),
|
||||
name = TTF_TAG('n','a','m','e'),
|
||||
OS_2 = TTF_TAG('O','S','/','2'),
|
||||
post = TTF_TAG('p','o','s','t'),
|
||||
prep = TTF_TAG('p','r','e','p')
|
||||
};
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------------------------
|
||||
Class providing utility methods to parse a TrueType font file (TTF).
|
||||
Callling application handles all file input and memory allocation.
|
||||
Assumes minimal knowledge of TTF file format.
|
||||
----------------------------------------------------------------------------------------------*/
|
||||
////////////////////////////////// tools to find & check TTF tables
|
||||
bool GetHeaderInfo(size_t & lOffset, size_t & lSize);
|
||||
bool CheckHeader(const void * pHdr);
|
||||
bool GetTableDirInfo(const void * pHdr, size_t & lOffset, size_t & lSize);
|
||||
bool GetTableInfo(const Tag TableTag, const void * pHdr, const void * pTableDir,
|
||||
size_t & lOffset, size_t & lSize);
|
||||
bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize);
|
||||
|
||||
////////////////////////////////// simple font wide info
|
||||
size_t GlyphCount(const void * pMaxp);
|
||||
#ifdef ALL_TTFUTILS
|
||||
size_t MaxCompositeComponentCount(const void * pMaxp);
|
||||
size_t MaxCompositeLevelCount(const void * pMaxp);
|
||||
size_t LocaGlyphCount(size_t lLocaSize, const void * pHead); // throw (std::domain_error);
|
||||
#endif
|
||||
int DesignUnits(const void * pHead);
|
||||
#ifdef ALL_TTFUTILS
|
||||
int HeadTableCheckSum(const void * pHead);
|
||||
void HeadTableCreateTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD);
|
||||
void HeadTableModifyTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD);
|
||||
bool IsItalic(const void * pHead);
|
||||
int FontAscent(const void * pOs2);
|
||||
int FontDescent(const void * pOs2);
|
||||
bool FontOs2Style(const void *pOs2, bool & fBold, bool & fItalic);
|
||||
bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize);
|
||||
bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize);
|
||||
bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize);
|
||||
bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize);
|
||||
int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
|
||||
const char * pPostName);
|
||||
#endif
|
||||
|
||||
////////////////////////////////// utility methods helpful for name table
|
||||
bool GetNameInfo(const void * pName, int nPlatformId, int nEncodingId,
|
||||
int nLangId, int nNameId, size_t & lOffset, size_t & lSize);
|
||||
//size_t NameTableLength(const byte * pTable);
|
||||
#ifdef ALL_TTFUTILS
|
||||
int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId,
|
||||
int *nameIdList, int cNameIds, short *langIdList);
|
||||
void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument);
|
||||
#endif
|
||||
|
||||
////////////////////////////////// cmap lookup tools
|
||||
const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3,
|
||||
int nEncodingId = 1, size_t length = 0);
|
||||
bool CheckCmapSubtable4(const void * pCmap31, const void * pCmapEnd /*, unsigned int maxgid*/);
|
||||
gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0);
|
||||
unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnicodeId,
|
||||
int * pRangeKey = 0);
|
||||
bool CheckCmapSubtable12(const void *pCmap310, const void * pCmapEnd /*, unsigned int maxgid*/);
|
||||
gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey = 0);
|
||||
unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUnicodeId,
|
||||
int * pRangeKey = 0);
|
||||
|
||||
///////////////////////////////// horizontal metric data for a glyph
|
||||
bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize,
|
||||
const void * pHhea, int & nLsb, unsigned int & nAdvWid);
|
||||
|
||||
////////////////////////////////// primitives for loca and glyf lookup
|
||||
size_t LocaLookup(gid16 nGlyphId, const void * pLoca, size_t lLocaSize,
|
||||
const void * pHead); // throw (std::out_of_range);
|
||||
void * GlyfLookup(const void * pGlyf, size_t lGlyfOffset, size_t lTableLen);
|
||||
|
||||
////////////////////////////////// primitves for simple glyph data
|
||||
bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin,
|
||||
int & xMax, int & yMax);
|
||||
|
||||
#ifdef ALL_TTFUTILS
|
||||
int GlyfContourCount(const void * pSimpleGlyf);
|
||||
bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint,
|
||||
int cnPointsTotal, size_t & cnPoints);
|
||||
bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
|
||||
char * prgbFlag, int cnPointsTotal, int & cnPoints);
|
||||
|
||||
// primitive to find the glyph ids in a composite glyph
|
||||
bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId,
|
||||
size_t cnCompIdTotal, size_t & cnCompId);
|
||||
// primitive to find the placement data for a component in a composite glyph
|
||||
bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId,
|
||||
bool fOffset, int & a, int & b);
|
||||
// primitive to find the transform data for a component in a composite glyph
|
||||
bool GetComponentTransform(const void * pSimpleGlyf, int nCompId,
|
||||
float & flt11, float & flt12, float & flt21, float & flt22, bool & fTransOffset);
|
||||
#endif
|
||||
|
||||
////////////////////////////////// operate on composite or simple glyph (auto glyf lookup)
|
||||
void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
|
||||
size_t lGlyfSize, size_t lLocaSize, const void * pHead); // primitive used by below methods
|
||||
|
||||
#ifdef ALL_TTFUTILS
|
||||
// below are primary user methods for handling glyf data
|
||||
bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead);
|
||||
bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
|
||||
size_t lGlyfSize, size_t lLocaSize, const void * pHead);
|
||||
|
||||
bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca, size_t lGlyfSize, size_t lLocaSize,
|
||||
const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax);
|
||||
bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
|
||||
size_t lGlyfSize, size_t lLocaSize, const void *pHead, size_t & cnContours);
|
||||
bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
|
||||
size_t lGlyfSize, size_t lLocaSize, const void * pHead, int * prgnContourEndPoint, size_t cnPoints);
|
||||
bool GlyfPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
|
||||
size_t lGlyfSize, size_t lLocaSize, const void * pHead, const int * prgnContourEndPoint, size_t cnEndPoints,
|
||||
int * prgnX, int * prgnY, bool * prgfOnCurve, size_t cnPoints);
|
||||
|
||||
// utitily method used by high-level GlyfPoints
|
||||
bool SimplifyFlags(char * prgbFlags, int cnPoints);
|
||||
bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints);
|
||||
#endif
|
||||
|
||||
} // end of namespace TtfUtil
|
||||
} // end of namespace graphite2
|
228
thirdparty/graphite/src/inc/UtfCodec.h
vendored
Normal file
228
thirdparty/graphite/src/inc/UtfCodec.h
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2011, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include "inc/Main.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
typedef uint32 uchar_t;
|
||||
|
||||
template <int N>
|
||||
struct _utf_codec
|
||||
{
|
||||
typedef uchar_t codeunit_t;
|
||||
|
||||
static void put(codeunit_t * cp, const uchar_t , int8 & len) throw();
|
||||
static uchar_t get(const codeunit_t * cp, int8 & len) throw();
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * const e) throw();
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct _utf_codec<32>
|
||||
{
|
||||
private:
|
||||
static const uchar_t limit = 0x110000;
|
||||
public:
|
||||
typedef uint32 codeunit_t;
|
||||
|
||||
inline
|
||||
static void put(codeunit_t * cp, const uchar_t usv, int8 & l) throw()
|
||||
{
|
||||
*cp = usv; l = 1;
|
||||
}
|
||||
|
||||
inline
|
||||
static uchar_t get(const codeunit_t * cp, int8 & l) throw()
|
||||
{
|
||||
if (cp[0] < limit) { l = 1; return cp[0]; }
|
||||
else { l = -1; return 0xFFFD; }
|
||||
}
|
||||
|
||||
inline
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * const e) throw()
|
||||
{
|
||||
return s <= e;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct _utf_codec<16>
|
||||
{
|
||||
private:
|
||||
static const int32 lead_offset = 0xD800 - (0x10000 >> 10);
|
||||
static const int32 surrogate_offset = 0x10000 - (0xD800 << 10) - 0xDC00;
|
||||
public:
|
||||
typedef uint16 codeunit_t;
|
||||
|
||||
inline
|
||||
static void put(codeunit_t * cp, const uchar_t usv, int8 & l) throw()
|
||||
{
|
||||
if (usv < 0x10000) { l = 1; cp[0] = codeunit_t(usv); }
|
||||
else
|
||||
{
|
||||
cp[0] = codeunit_t(lead_offset + (usv >> 10));
|
||||
cp[1] = codeunit_t(0xDC00 + (usv & 0x3FF));
|
||||
l = 2;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
static uchar_t get(const codeunit_t * cp, int8 & l) throw()
|
||||
{
|
||||
const uint32 uh = cp[0];
|
||||
l = 1;
|
||||
|
||||
if (uh < 0xD800|| uh > 0xDFFF) { return uh; }
|
||||
if (uh > 0xDBFF) { l = -1; return 0xFFFD; }
|
||||
const uint32 ul = cp[1];
|
||||
if (ul < 0xDC00 || ul > 0xDFFF) { l = -1; return 0xFFFD; }
|
||||
++l;
|
||||
return (uh<<10) + ul + surrogate_offset;
|
||||
}
|
||||
|
||||
inline
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * const e) throw()
|
||||
{
|
||||
const ptrdiff_t n = e-s;
|
||||
if (n <= 0) return n == 0;
|
||||
const uint32 u = *(e-1); // Get the last codepoint
|
||||
return (u < 0xD800 || u > 0xDBFF);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct _utf_codec<8>
|
||||
{
|
||||
private:
|
||||
static const int8 sz_lut[16];
|
||||
static const byte mask_lut[5];
|
||||
static const uchar_t limit = 0x110000;
|
||||
|
||||
public:
|
||||
typedef uint8 codeunit_t;
|
||||
|
||||
inline
|
||||
static void put(codeunit_t * cp, const uchar_t usv, int8 & l) throw()
|
||||
{
|
||||
if (usv < 0x80) {l = 1; cp[0] = usv; return; }
|
||||
if (usv < 0x0800) {l = 2; cp[0] = 0xC0 + (usv >> 6); cp[1] = 0x80 + (usv & 0x3F); return; }
|
||||
if (usv < 0x10000) {l = 3; cp[0] = 0xE0 + (usv >> 12); cp[1] = 0x80 + ((usv >> 6) & 0x3F); cp[2] = 0x80 + (usv & 0x3F); return; }
|
||||
else {l = 4; cp[0] = 0xF0 + (usv >> 18); cp[1] = 0x80 + ((usv >> 12) & 0x3F); cp[2] = 0x80 + ((usv >> 6) & 0x3F); cp[3] = 0x80 + (usv & 0x3F); return; }
|
||||
}
|
||||
|
||||
inline
|
||||
static uchar_t get(const codeunit_t * cp, int8 & l) throw()
|
||||
{
|
||||
const int8 seq_sz = sz_lut[*cp >> 4];
|
||||
uchar_t u = *cp & mask_lut[seq_sz];
|
||||
l = 1;
|
||||
bool toolong = false;
|
||||
|
||||
switch(seq_sz) {
|
||||
case 4: u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong = (u < 0x10); GR_FALLTHROUGH;
|
||||
// no break
|
||||
case 3: u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong |= (u < 0x20); GR_FALLTHROUGH;
|
||||
// no break
|
||||
case 2: u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong |= (u < 0x80); GR_FALLTHROUGH;
|
||||
// no break
|
||||
case 1: break;
|
||||
case 0: l = -1; return 0xFFFD;
|
||||
}
|
||||
|
||||
if (l != seq_sz || toolong || u >= limit)
|
||||
{
|
||||
l = -l;
|
||||
return 0xFFFD;
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
inline
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * const e) throw()
|
||||
{
|
||||
const ptrdiff_t n = e-s;
|
||||
if (n <= 0) return n == 0;
|
||||
s += (n-1);
|
||||
if (*s < 0x80) return true;
|
||||
if (*s >= 0xC0) return false;
|
||||
if (n == 1) return true;
|
||||
if (*--s < 0x80) return true;
|
||||
if (*s >= 0xE0) return false;
|
||||
if (n == 2 || *s >= 0xC0) return true;
|
||||
if (*--s < 0x80) return true;
|
||||
if (*s >= 0xF0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename C>
|
||||
class _utf_iterator
|
||||
{
|
||||
typedef _utf_codec<sizeof(C)*8> codec;
|
||||
|
||||
C * cp;
|
||||
mutable int8 sl;
|
||||
|
||||
public:
|
||||
typedef C codeunit_type;
|
||||
typedef uchar_t value_type;
|
||||
typedef uchar_t * pointer;
|
||||
|
||||
class reference
|
||||
{
|
||||
const _utf_iterator & _i;
|
||||
|
||||
reference(const _utf_iterator & i): _i(i) {}
|
||||
public:
|
||||
operator value_type () const throw () { return codec::get(_i.cp, _i.sl); }
|
||||
reference & operator = (const value_type usv) throw() { codec::put(_i.cp, usv, _i.sl); return *this; }
|
||||
|
||||
friend class _utf_iterator;
|
||||
};
|
||||
|
||||
|
||||
_utf_iterator(const void * us=0) : cp(reinterpret_cast<C *>(const_cast<void *>(us))), sl(1) { }
|
||||
|
||||
_utf_iterator & operator ++ () { cp += abs(sl); return *this; }
|
||||
_utf_iterator operator ++ (int) { _utf_iterator tmp(*this); operator++(); return tmp; }
|
||||
|
||||
bool operator == (const _utf_iterator & rhs) const throw() { return cp >= rhs.cp; }
|
||||
bool operator != (const _utf_iterator & rhs) const throw() { return !operator==(rhs); }
|
||||
|
||||
reference operator * () const throw() { return *this; }
|
||||
pointer operator ->() const throw() { return &operator *(); }
|
||||
|
||||
operator codeunit_type * () const throw() { return cp; }
|
||||
|
||||
bool error() const throw() { return sl < 1; }
|
||||
bool validate(const _utf_iterator & e) { return codec::validate(cp, e.cp); }
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
struct utf
|
||||
{
|
||||
typedef typename _utf_codec<sizeof(C)*8>::codeunit_t codeunit_t;
|
||||
|
||||
typedef _utf_iterator<C> iterator;
|
||||
typedef _utf_iterator<const C> const_iterator;
|
||||
|
||||
inline
|
||||
static bool validate(codeunit_t * s, codeunit_t * e) throw() {
|
||||
return _utf_codec<sizeof(C)*8>::validate(s,e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef utf<uint32> utf32;
|
||||
typedef utf<uint16> utf16;
|
||||
typedef utf<uint8> utf8;
|
||||
|
||||
} // namespace graphite2
|
127
thirdparty/graphite/src/inc/bits.h
vendored
Normal file
127
thirdparty/graphite/src/inc/bits.h
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2012, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace graphite2
|
||||
{
|
||||
|
||||
|
||||
#if defined GRAPHITE2_BUILTINS && (defined __GNUC__ || defined __clang__)
|
||||
|
||||
template<typename T>
|
||||
inline unsigned int bit_set_count(T v)
|
||||
{
|
||||
return __builtin_popcount(v);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int bit_set_count(int16 v)
|
||||
{
|
||||
return __builtin_popcount(static_cast<uint16>(v));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int bit_set_count(int8 v)
|
||||
{
|
||||
return __builtin_popcount(static_cast<uint8>(v));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int bit_set_count(unsigned long v)
|
||||
{
|
||||
return __builtin_popcountl(v);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int bit_set_count(signed long v)
|
||||
{
|
||||
return __builtin_popcountl(v);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int bit_set_count(unsigned long long v)
|
||||
{
|
||||
return __builtin_popcountll(v);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int bit_set_count(signed long long v)
|
||||
{
|
||||
return __builtin_popcountll(v);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<typename T>
|
||||
inline unsigned int bit_set_count(T v)
|
||||
{
|
||||
static size_t const ONES = ~0;
|
||||
|
||||
v = v - ((v >> 1) & T(ONES/3)); // temp
|
||||
v = (v & T(ONES/15*3)) + ((v >> 2) & T(ONES/15*3)); // temp
|
||||
v = (v + (v >> 4)) & T(ONES/255*15); // temp
|
||||
return (T)(v * T(ONES/255)) >> (sizeof(T)-1)*8; // count
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//TODO: Changed these to uintmax_t when we go to C++11
|
||||
template<int S>
|
||||
inline size_t _mask_over_val(size_t v)
|
||||
{
|
||||
v = _mask_over_val<S/2>(v);
|
||||
v |= v >> S*4;
|
||||
return v;
|
||||
}
|
||||
|
||||
//TODO: Changed these to uintmax_t when we go to C++11
|
||||
template<>
|
||||
inline size_t _mask_over_val<1>(size_t v)
|
||||
{
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T mask_over_val(T v)
|
||||
{
|
||||
return T(_mask_over_val<sizeof(T)>(v));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline unsigned long next_highest_power2(T v)
|
||||
{
|
||||
return _mask_over_val<sizeof(T)>(v-1)+1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline unsigned int log_binary(T v)
|
||||
{
|
||||
return bit_set_count(mask_over_val(v))-1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T has_zero(const T x)
|
||||
{
|
||||
return (x - T(~T(0)/255)) & ~x & T(~T(0)/255*128);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T zero_bytes(const T x, unsigned char n)
|
||||
{
|
||||
const T t = T(~T(0)/255*n);
|
||||
return T((has_zero(x^t) >> 7)*n);
|
||||
}
|
||||
|
||||
#if 0
|
||||
inline float float_round(float x, uint32 m)
|
||||
{
|
||||
*reinterpret_cast<unsigned int *>(&x) &= m;
|
||||
return *reinterpret_cast<float *>(&x);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
66
thirdparty/graphite/src/inc/debug.h
vendored
Normal file
66
thirdparty/graphite/src/inc/debug.h
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2011, SIL International, All rights reserved.
|
||||
|
||||
// debug.h
|
||||
//
|
||||
// Created on: 22 Dec 2011
|
||||
// Author: tim
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
|
||||
#include <utility>
|
||||
#include "inc/json.h"
|
||||
#include "inc/Position.h"
|
||||
|
||||
namespace graphite2
|
||||
{
|
||||
|
||||
class CharInfo;
|
||||
class Segment;
|
||||
class Slot;
|
||||
|
||||
typedef std::pair<const Segment * const, const Slot * const> dslot;
|
||||
struct objectid
|
||||
{
|
||||
char name[16];
|
||||
objectid(const dslot &) throw();
|
||||
objectid(const Segment * const p) throw();
|
||||
};
|
||||
|
||||
|
||||
json & operator << (json & j, const Position &) throw();
|
||||
json & operator << (json & j, const Rect &) throw();
|
||||
json & operator << (json & j, const CharInfo &) throw();
|
||||
json & operator << (json & j, const dslot &) throw();
|
||||
json & operator << (json & j, const objectid &) throw();
|
||||
json & operator << (json & j, const telemetry &) throw();
|
||||
|
||||
|
||||
|
||||
inline
|
||||
json & operator << (json & j, const Position & p) throw()
|
||||
{
|
||||
return j << json::flat << json::array << p.x << p.y << json::close;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
json & operator << (json & j, const Rect & p) throw()
|
||||
{
|
||||
return j << json::flat << json::array << p.bl.x << p.bl.y << p.tr.x << p.tr.y << json::close;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
json & operator << (json & j, const objectid & sid) throw()
|
||||
{
|
||||
return j << sid.name;
|
||||
}
|
||||
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
#endif //!defined GRAPHITE2_NTRACING
|
||||
|
155
thirdparty/graphite/src/inc/json.h
vendored
Normal file
155
thirdparty/graphite/src/inc/json.h
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2011, SIL International, All rights reserved.
|
||||
|
||||
// JSON pretty printer for graphite font debug output logging.
|
||||
// Created on: 15 Dec 2011
|
||||
// Author: Tim Eves
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include "inc/List.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class json
|
||||
{
|
||||
// Prevent copying
|
||||
json(const json &);
|
||||
json & operator = (const json &);
|
||||
|
||||
typedef void (*_context_t)(json &);
|
||||
|
||||
FILE * const _stream;
|
||||
char _contexts[128], // context stack
|
||||
* _context, // current context (top of stack)
|
||||
* _flatten; // if !0 points to context above which
|
||||
// pretty printed output should occur.
|
||||
Vector<void *> _env;
|
||||
|
||||
void context(const char current) throw();
|
||||
void indent(const int d=0) throw();
|
||||
void push_context(const char, const char) throw();
|
||||
void pop_context() throw();
|
||||
|
||||
public:
|
||||
class closer;
|
||||
|
||||
using string = const char *;
|
||||
using number = double;
|
||||
enum class integer : std::intmax_t {};
|
||||
enum class integer_u : std::uintmax_t {};
|
||||
using boolean = bool;
|
||||
static const std::nullptr_t null;
|
||||
|
||||
void setenv(unsigned int index, void *val) { _env.reserve(index + 1); if (index >= _env.size()) _env.insert(_env.end(), _env.size() - index + 1, 0); _env[index] = val; }
|
||||
void *getenv(unsigned int index) const { return _env[index]; }
|
||||
const Vector<void *> &getenvs() const { return _env; }
|
||||
|
||||
static void flat(json &) throw();
|
||||
static void close(json &) throw();
|
||||
static void object(json &) throw();
|
||||
static void array(json &) throw();
|
||||
static void item(json &) throw();
|
||||
|
||||
json(FILE * stream) throw();
|
||||
~json() throw ();
|
||||
|
||||
FILE * stream() const throw();
|
||||
|
||||
json & operator << (string) throw();
|
||||
json & operator << (number) throw();
|
||||
json & operator << (integer) throw();
|
||||
json & operator << (integer_u) throw();
|
||||
json & operator << (boolean) throw();
|
||||
json & operator << (std::nullptr_t) throw();
|
||||
json & operator << (_context_t) throw();
|
||||
|
||||
operator bool() const throw();
|
||||
bool good() const throw();
|
||||
bool eof() const throw();
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
};
|
||||
|
||||
class json::closer
|
||||
{
|
||||
// Prevent copying.
|
||||
closer(const closer &);
|
||||
closer & operator = (const closer &);
|
||||
|
||||
json * const _j;
|
||||
public:
|
||||
closer(json * const j) : _j(j) {}
|
||||
~closer() throw() { if (_j) *_j << close; }
|
||||
};
|
||||
|
||||
inline
|
||||
json::json(FILE * s) throw()
|
||||
: _stream(s), _context(_contexts), _flatten(0)
|
||||
{
|
||||
if (good())
|
||||
fflush(s);
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
json::~json() throw ()
|
||||
{
|
||||
while (_context > _contexts) pop_context();
|
||||
}
|
||||
|
||||
inline
|
||||
FILE * json::stream() const throw() { return _stream; }
|
||||
|
||||
|
||||
inline
|
||||
json & json::operator << (json::_context_t ctxt) throw()
|
||||
{
|
||||
ctxt(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
json & operator << (json & j, signed char d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned char d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, short int d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned short int d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, int d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned int d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, long int d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned long int d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, long long int d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned long long int d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json::operator bool() const throw() { return good(); }
|
||||
|
||||
inline
|
||||
bool json::good() const throw() { return _stream && ferror(_stream) == 0; }
|
||||
|
||||
inline
|
||||
bool json::eof() const throw() { return feof(_stream) != 0; }
|
||||
|
||||
} // namespace graphite2
|
427
thirdparty/graphite/src/inc/locale2lcid.h
vendored
Normal file
427
thirdparty/graphite/src/inc/locale2lcid.h
vendored
Normal file
@@ -0,0 +1,427 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include "inc/Main.h"
|
||||
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
struct IsoLangEntry
|
||||
{
|
||||
unsigned short mnLang;
|
||||
char maLangStr[4];
|
||||
char maCountry[3];
|
||||
};
|
||||
|
||||
// Windows Language ID, Locale ISO-639 language, country code as used in
|
||||
// naming table of OpenType fonts
|
||||
const IsoLangEntry LANG_ENTRIES[] = {
|
||||
{ 0x0401, "ar","SA" }, // Arabic Saudi Arabia
|
||||
{ 0x0402, "bg","BG" }, // Bulgarian Bulgaria
|
||||
{ 0x0403, "ca","ES" }, // Catalan Catalan
|
||||
{ 0x0404, "zh","TW" }, // Chinese Taiwan
|
||||
{ 0x0405, "cs","CZ" }, // Czech Czech Republic
|
||||
{ 0x0406, "da","DK" }, // Danish Denmark
|
||||
{ 0x0407, "de","DE" }, // German Germany
|
||||
{ 0x0408, "el","GR" }, // Greek Greece
|
||||
{ 0x0409, "en","US" }, // English United States
|
||||
{ 0x040A, "es","ES" }, // Spanish (Traditional Sort) Spain
|
||||
{ 0x040B, "fi","FI" }, // Finnish Finland
|
||||
{ 0x040C, "fr","FR" }, // French France
|
||||
{ 0x040D, "he","IL" }, // Hebrew Israel
|
||||
{ 0x040E, "hu","HU" }, // Hungarian Hungary
|
||||
{ 0x040F, "is","IS" }, // Icelandic Iceland
|
||||
{ 0x0410, "it","IT" }, // Italian Italy
|
||||
{ 0x0411, "jp","JP" }, // Japanese Japan
|
||||
{ 0x0412, "ko","KR" }, // Korean Korea
|
||||
{ 0x0413, "nl","NL" }, // Dutch Netherlands
|
||||
{ 0x0414, "no","NO" }, // Norwegian (Bokmal) Norway
|
||||
{ 0x0415, "pl","PL" }, // Polish Poland
|
||||
{ 0x0416, "pt","BR" }, // Portuguese Brazil
|
||||
{ 0x0417, "rm","CH" }, // Romansh Switzerland
|
||||
{ 0x0418, "ro","RO" }, // Romanian Romania
|
||||
{ 0x0419, "ru","RU" }, // Russian Russia
|
||||
{ 0x041A, "hr","HR" }, // Croatian Croatia
|
||||
{ 0x041B, "sk","SK" }, // Slovak Slovakia
|
||||
{ 0x041C, "sq","AL" }, // Albanian Albania
|
||||
{ 0x041D, "sv","SE" }, // Swedish Sweden
|
||||
{ 0x041E, "th","TH" }, // Thai Thailand
|
||||
{ 0x041F, "tr","TR" }, // Turkish Turkey
|
||||
{ 0x0420, "ur","PK" }, // Urdu Islamic Republic of Pakistan
|
||||
{ 0x0421, "id","ID" }, // Indonesian Indonesia
|
||||
{ 0x0422, "uk","UA" }, // Ukrainian Ukraine
|
||||
{ 0x0423, "be","BY" }, // Belarusian Belarus
|
||||
{ 0x0424, "sl","SI" }, // Slovenian Slovenia
|
||||
{ 0x0425, "et","EE" }, // Estonian Estonia
|
||||
{ 0x0426, "lv","LV" }, // Latvian Latvia
|
||||
{ 0x0427, "lt","LT" }, // Lithuanian Lithuania
|
||||
{ 0x0428, "tg","TJ" }, // Tajik (Cyrillic) Tajikistan
|
||||
{ 0x042A, "vi","VN" }, // Vietnamese Vietnam
|
||||
{ 0x042B, "hy","AM" }, // Armenian Armenia
|
||||
{ 0x042C, "az","AZ" }, // Azeri (Latin) Azerbaijan
|
||||
{ 0x042D, "eu","" }, // Basque Basque
|
||||
{ 0x042E, "hsb","DE" }, // Upper Sorbian Germany
|
||||
{ 0x042F, "mk","MK" }, // Macedonian (FYROM) Former Yugoslav Republic of Macedonia
|
||||
{ 0x0432, "tn","ZA" }, // Setswana South Africa
|
||||
{ 0x0434, "xh","ZA" }, // isiXhosa South Africa
|
||||
{ 0x0435, "zu","ZA" }, // isiZulu South Africa
|
||||
{ 0x0436, "af","ZA" }, // Afrikaans South Africa
|
||||
{ 0x0437, "ka","GE" }, // Georgian Georgia
|
||||
{ 0x0438, "fo","FO" }, // Faroese Faroe Islands
|
||||
{ 0x0439, "hi","IN" }, // Hindi India
|
||||
{ 0x043A, "mt","MT" }, // Maltese Malta
|
||||
{ 0x043B, "se","NO" }, // Sami (Northern) Norway
|
||||
{ 0x043E, "ms","MY" }, // Malay Malaysia
|
||||
{ 0x043F, "kk","KZ" }, // Kazakh Kazakhstan
|
||||
{ 0x0440, "ky","KG" }, // Kyrgyz Kyrgyzstan
|
||||
{ 0x0441, "sw","KE" }, // Kiswahili Kenya
|
||||
{ 0x0442, "tk","TM" }, // Turkmen Turkmenistan
|
||||
{ 0x0443, "uz","UZ" }, // Uzbek (Latin) Uzbekistan
|
||||
{ 0x0444, "tt","RU" }, // Tatar Russia
|
||||
{ 0x0445, "bn","IN" }, // Bengali India
|
||||
{ 0x0446, "pa","IN" }, // Punjabi India
|
||||
{ 0x0447, "gu","IN" }, // Gujarati India
|
||||
{ 0x0448, "or","IN" }, // Oriya India
|
||||
{ 0x0448, "wo","SN" }, // Wolof Senegal
|
||||
{ 0x0449, "ta","IN" }, // Tamil India
|
||||
{ 0x044A, "te","IN" }, // Telugu India
|
||||
{ 0x044B, "kn","IN" }, // Kannada India
|
||||
{ 0x044C, "ml","IN" }, // Malayalam India
|
||||
{ 0x044D, "as","IN" }, // Assamese India
|
||||
{ 0x044E, "mr","IN" }, // Marathi India
|
||||
{ 0x044F, "sa","IN" }, // Sanskrit India
|
||||
{ 0x0450, "mn","MN" }, // Mongolian (Cyrillic) Mongolia
|
||||
{ 0x0451, "bo","CN" }, // Tibetan PRC
|
||||
{ 0x0452, "cy","GB" }, // Welsh United Kingdom
|
||||
{ 0x0453, "km","KH" }, // Khmer Cambodia
|
||||
{ 0x0454, "lo","LA" }, // Lao Lao P.D.R.
|
||||
{ 0x0455, "my","MM" }, // Burmese Myanmar - not listed in Microsoft docs anymore
|
||||
{ 0x0456, "gl","ES" }, // Galician Galician
|
||||
{ 0x0457, "kok","IN" }, // Konkani India
|
||||
{ 0x045A, "syr","TR" }, // Syriac Syria
|
||||
{ 0x045B, "si","LK" }, // Sinhala Sri Lanka
|
||||
{ 0x045D, "iu","CA" }, // Inuktitut Canada
|
||||
{ 0x045E, "am","ET" }, // Amharic Ethiopia
|
||||
{ 0x0461, "ne","NP" }, // Nepali Nepal
|
||||
{ 0x0462, "fy","NL" }, // Frisian Netherlands
|
||||
{ 0x0463, "ps","AF" }, // Pashto Afghanistan
|
||||
{ 0x0464, "fil","PH" }, // Filipino Philippines
|
||||
{ 0x0465, "dv","MV" }, // Divehi Maldives
|
||||
{ 0x0468, "ha","NG" }, // Hausa (Latin) Nigeria
|
||||
{ 0x046A, "yo","NG" }, // Yoruba Nigeria
|
||||
{ 0x046B, "qu","BO" }, // Quechua Bolivia
|
||||
{ 0x046C, "st","ZA" }, // Sesotho sa Leboa South Africa
|
||||
{ 0x046D, "ba","RU" }, // Bashkir Russia
|
||||
{ 0x046E, "lb","LU" }, // Luxembourgish Luxembourg
|
||||
{ 0x046F, "kl","GL" }, // Greenlandic Greenland
|
||||
{ 0x0470, "ig","NG" }, // Igbo Nigeria
|
||||
{ 0x0478, "ii","CN" }, // Yi PRC
|
||||
{ 0x047A, "arn","CL" }, // Mapudungun Chile
|
||||
{ 0x047C, "moh","CA" }, // Mohawk Mohawk
|
||||
{ 0x047E, "br","FR" }, // Breton France
|
||||
{ 0x0480, "ug","CN" }, // Uighur PRC
|
||||
{ 0x0481, "mi","NZ" }, // Maori New Zealand
|
||||
{ 0x0482, "oc","FR" }, // Occitan France
|
||||
{ 0x0483, "co","FR" }, // Corsican France
|
||||
{ 0x0484, "gsw","FR" }, // Alsatian France
|
||||
{ 0x0485, "sah","RU" }, // Yakut Russia
|
||||
{ 0x0486, "qut","GT" }, // K'iche Guatemala
|
||||
{ 0x0487, "rw","RW" }, // Kinyarwanda Rwanda
|
||||
{ 0x048C, "gbz","AF" }, // Dari Afghanistan
|
||||
{ 0x0801, "ar","IQ" }, // Arabic Iraq
|
||||
{ 0x0804, "zn","CH" }, // Chinese People's Republic of China
|
||||
{ 0x0807, "de","CH" }, // German Switzerland
|
||||
{ 0x0809, "en","GB" }, // English United Kingdom
|
||||
{ 0x080A, "es","MX" }, // Spanish Mexico
|
||||
{ 0x080C, "fr","BE" }, // French Belgium
|
||||
{ 0x0810, "it","CH" }, // Italian Switzerland
|
||||
{ 0x0813, "nl","BE" }, // Dutch Belgium
|
||||
{ 0x0814, "nn","NO" }, // Norwegian (Nynorsk) Norway
|
||||
{ 0x0816, "pt","PT" }, // Portuguese Portugal
|
||||
{ 0x081A, "sh","RS" }, // Serbian (Latin) Serbia
|
||||
{ 0x081D, "sv","FI" }, // Sweden Finland
|
||||
{ 0x082C, "az","AZ" }, // Azeri (Cyrillic) Azerbaijan
|
||||
{ 0x082E, "dsb","DE" }, // Lower Sorbian Germany
|
||||
{ 0x083B, "se","SE" }, // Sami (Northern) Sweden
|
||||
{ 0x083C, "ga","IE" }, // Irish Ireland
|
||||
{ 0x083E, "ms","BN" }, // Malay Brunei Darussalam
|
||||
{ 0x0843, "uz","UZ" }, // Uzbek (Cyrillic) Uzbekistan
|
||||
{ 0x0845, "bn","BD" }, // Bengali Bangladesh
|
||||
{ 0x0850, "mn","MN" }, // Mongolian (Traditional) People's Republic of China
|
||||
{ 0x085D, "iu","CA" }, // Inuktitut (Latin) Canada
|
||||
{ 0x085F, "ber","DZ" }, // Tamazight (Latin) Algeria
|
||||
{ 0x086B, "es","EC" }, // Quechua Ecuador
|
||||
{ 0x0C01, "ar","EG" }, // Arabic Egypt
|
||||
{ 0x0C04, "zh","HK" }, // Chinese Hong Kong S.A.R.
|
||||
{ 0x0C07, "de","AT" }, // German Austria
|
||||
{ 0x0C09, "en","AU" }, // English Australia
|
||||
{ 0x0C0A, "es","ES" }, // Spanish (Modern Sort) Spain
|
||||
{ 0x0C0C, "fr","CA" }, // French Canada
|
||||
{ 0x0C1A, "sr","CS" }, // Serbian (Cyrillic) Serbia
|
||||
{ 0x0C3B, "se","FI" }, // Sami (Northern) Finland
|
||||
{ 0x0C6B, "qu","PE" }, // Quechua Peru
|
||||
{ 0x1001, "ar","LY" }, // Arabic Libya
|
||||
{ 0x1004, "zh","SG" }, // Chinese Singapore
|
||||
{ 0x1007, "de","LU" }, // German Luxembourg
|
||||
{ 0x1009, "en","CA" }, // English Canada
|
||||
{ 0x100A, "es","GT" }, // Spanish Guatemala
|
||||
{ 0x100C, "fr","CH" }, // French Switzerland
|
||||
{ 0x101A, "hr","BA" }, // Croatian (Latin) Bosnia and Herzegovina
|
||||
{ 0x103B, "smj","NO" }, // Sami (Lule) Norway
|
||||
{ 0x1401, "ar","DZ" }, // Arabic Algeria
|
||||
{ 0x1404, "zh","MO" }, // Chinese Macao S.A.R.
|
||||
{ 0x1407, "de","LI" }, // German Liechtenstein
|
||||
{ 0x1409, "en","NZ" }, // English New Zealand
|
||||
{ 0x140A, "es","CR" }, // Spanish Costa Rica
|
||||
{ 0x140C, "fr","LU" }, // French Luxembourg
|
||||
{ 0x141A, "bs","BA" }, // Bosnian (Latin) Bosnia and Herzegovina
|
||||
{ 0x143B, "smj","SE" }, // Sami (Lule) Sweden
|
||||
{ 0x1801, "ar","MA" }, // Arabic Morocco
|
||||
{ 0x1809, "en","IE" }, // English Ireland
|
||||
{ 0x180A, "es","PA" }, // Spanish Panama
|
||||
{ 0x180C, "fr","MC" }, // French Principality of Monoco
|
||||
{ 0x181A, "sh","BA" }, // Serbian (Latin) Bosnia and Herzegovina
|
||||
{ 0x183B, "sma","NO" }, // Sami (Southern) Norway
|
||||
{ 0x1C01, "ar","TN" }, // Arabic Tunisia
|
||||
{ 0x1C09, "en","ZA" }, // English South Africa
|
||||
{ 0x1C0A, "es","DO" }, // Spanish Dominican Republic
|
||||
{ 0x1C1A, "sr","BA" }, // Serbian (Cyrillic) Bosnia and Herzegovina
|
||||
{ 0x1C3B, "sma","SE" }, // Sami (Southern) Sweden
|
||||
{ 0x2001, "ar","OM" }, // Arabic Oman
|
||||
{ 0x2009, "en","JM" }, // English Jamaica
|
||||
{ 0x200A, "es","VE" }, // Spanish Venezuela
|
||||
{ 0x201A, "bs","BA" }, // Bosnian (Cyrillic) Bosnia and Herzegovina
|
||||
{ 0x203B, "sms","FI" }, // Sami (Skolt) Finland
|
||||
{ 0x2401, "ar","YE" }, // Arabic Yemen
|
||||
{ 0x2409, "en","BS" }, // English Caribbean
|
||||
{ 0x240A, "es","CO" }, // Spanish Colombia
|
||||
{ 0x243B, "smn","FI" }, // Sami (Inari) Finland
|
||||
{ 0x2801, "ar","SY" }, // Arabic Syria
|
||||
{ 0x2809, "en","BZ" }, // English Belize
|
||||
{ 0x280A, "es","PE" }, // Spanish Peru
|
||||
{ 0x2C01, "ar","JO" }, // Arabic Jordan
|
||||
{ 0x2C09, "en","TT" }, // English Trinidad and Tobago
|
||||
{ 0x2C0A, "es","AR" }, // Spanish Argentina
|
||||
{ 0x3001, "ar","LB" }, // Arabic Lebanon
|
||||
{ 0x3009, "en","ZW" }, // English Zimbabwe
|
||||
{ 0x300A, "es","EC" }, // Spanish Ecuador
|
||||
{ 0x3401, "ar","KW" }, // Arabic Kuwait
|
||||
{ 0x3409, "en","PH" }, // English Republic of the Philippines
|
||||
{ 0x340A, "es","CL" }, // Spanish Chile
|
||||
{ 0x3801, "ar","AE" }, // Arabic U.A.E.
|
||||
{ 0x380A, "es","UY" }, // Spanish Uruguay
|
||||
{ 0x3C01, "ar","BH" }, // Arabic Bahrain
|
||||
{ 0x3C0A, "es","PY" }, // Spanish Paraguay
|
||||
{ 0x4001, "ar","QA" }, // Arabic Qatar
|
||||
{ 0x4009, "en","IN" }, // English India
|
||||
{ 0x400A, "es","BO" }, // Spanish Bolivia
|
||||
{ 0x4409, "en","MY" }, // English Malaysia
|
||||
{ 0x440A, "es","SV" }, // Spanish El Salvador
|
||||
{ 0x4809, "en","SG" }, // English Singapore
|
||||
{ 0x480A, "es","HN" }, // Spanish Honduras
|
||||
{ 0x4C0A, "es","NI" }, // Spanish Nicaragua
|
||||
{ 0x500A, "es","PR" }, // Spanish Puerto Rico
|
||||
{ 0x540A, "es","US" } // Spanish United States
|
||||
};
|
||||
|
||||
class Locale2Lang
|
||||
{
|
||||
Locale2Lang(const Locale2Lang &);
|
||||
Locale2Lang & operator = (const Locale2Lang &);
|
||||
|
||||
public:
|
||||
Locale2Lang() : mSeedPosition(128)
|
||||
{
|
||||
memset((void*)mLangLookup, 0, sizeof(mLangLookup));
|
||||
// create a tri lookup on first 2 letters of language code
|
||||
static const int maxIndex = sizeof(LANG_ENTRIES)/sizeof(IsoLangEntry);
|
||||
for (int i = 0; i < maxIndex; i++)
|
||||
{
|
||||
size_t a = LANG_ENTRIES[i].maLangStr[0] - 'a';
|
||||
size_t b = LANG_ENTRIES[i].maLangStr[1] - 'a';
|
||||
if (mLangLookup[a][b])
|
||||
{
|
||||
const IsoLangEntry ** old = mLangLookup[a][b];
|
||||
int len = 1;
|
||||
while (old[len]) len++;
|
||||
len += 2;
|
||||
mLangLookup[a][b] = gralloc<const IsoLangEntry *>(len);
|
||||
if (!mLangLookup[a][b])
|
||||
{
|
||||
mLangLookup[a][b] = old;
|
||||
continue;
|
||||
}
|
||||
mLangLookup[a][b][--len] = NULL;
|
||||
mLangLookup[a][b][--len] = &LANG_ENTRIES[i];
|
||||
while (--len >= 0)
|
||||
{
|
||||
assert(len >= 0);
|
||||
mLangLookup[a][b][len] = old[len];
|
||||
}
|
||||
free(old);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLangLookup[a][b] = gralloc<const IsoLangEntry *>(2);
|
||||
if (!mLangLookup[a][b]) continue;
|
||||
mLangLookup[a][b][1] = NULL;
|
||||
mLangLookup[a][b][0] = &LANG_ENTRIES[i];
|
||||
}
|
||||
}
|
||||
while (2 * mSeedPosition < maxIndex)
|
||||
mSeedPosition *= 2;
|
||||
};
|
||||
~Locale2Lang()
|
||||
{
|
||||
for (int i = 0; i != 26; ++i)
|
||||
for (int j = 0; j != 26; ++j)
|
||||
free(mLangLookup[i][j]);
|
||||
}
|
||||
unsigned short getMsId(const char * locale) const
|
||||
{
|
||||
size_t length = strlen(locale);
|
||||
size_t langLength = length;
|
||||
const char * language = locale;
|
||||
const char * script = NULL;
|
||||
const char * region = NULL;
|
||||
size_t regionLength = 0;
|
||||
const char * dash = strchr(locale, '-');
|
||||
if (dash && (dash != locale))
|
||||
{
|
||||
langLength = (dash - locale);
|
||||
size_t nextPartLength = length - langLength - 1;
|
||||
if (nextPartLength >= 2)
|
||||
{
|
||||
script = ++dash;
|
||||
dash = strchr(dash, '-');
|
||||
if (dash)
|
||||
{
|
||||
nextPartLength = (dash - script);
|
||||
region = ++dash;
|
||||
}
|
||||
if (nextPartLength == 2 &&
|
||||
(locale[langLength+1] > 0x40) && (locale[langLength+1] < 0x5B) &&
|
||||
(locale[langLength+2] > 0x40) && (locale[langLength+2] < 0x5B))
|
||||
{
|
||||
region = script;
|
||||
regionLength = nextPartLength;
|
||||
script = NULL;
|
||||
}
|
||||
else if (nextPartLength == 4)
|
||||
{
|
||||
if (dash)
|
||||
{
|
||||
dash = strchr(dash, '-');
|
||||
if (dash)
|
||||
{
|
||||
nextPartLength = (dash - region);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextPartLength = langLength - (region - locale);
|
||||
}
|
||||
regionLength = nextPartLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
size_t a = 'e' - 'a';
|
||||
size_t b = 'n' - 'a';
|
||||
unsigned short langId = 0;
|
||||
int i = 0;
|
||||
switch (langLength)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
a = language[0] - 'a';
|
||||
b = language[1] - 'a';
|
||||
if ((a < 26) && (b < 26) && mLangLookup[a][b])
|
||||
{
|
||||
while (mLangLookup[a][b][i])
|
||||
{
|
||||
if (mLangLookup[a][b][i]->maLangStr[2] != '\0')
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (region && (strncmp(mLangLookup[a][b][i]->maCountry, region, regionLength) == 0))
|
||||
{
|
||||
langId = mLangLookup[a][b][i]->mnLang;
|
||||
break;
|
||||
}
|
||||
else if (langId == 0)
|
||||
{
|
||||
// possible fallback code
|
||||
langId = mLangLookup[a][b][i]->mnLang;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
a = language[0] - 'a';
|
||||
b = language[1] - 'a';
|
||||
if (mLangLookup[a][b])
|
||||
{
|
||||
while (mLangLookup[a][b][i])
|
||||
{
|
||||
if (mLangLookup[a][b][i]->maLangStr[2] != language[2])
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (region && (strncmp(mLangLookup[a][b][i]->maCountry, region, regionLength) == 0))
|
||||
{
|
||||
langId = mLangLookup[a][b][i]->mnLang;
|
||||
break;
|
||||
}
|
||||
else if (langId == 0)
|
||||
{
|
||||
// possible fallback code
|
||||
langId = mLangLookup[a][b][i]->mnLang;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (langId == 0) langId = 0x409;
|
||||
return langId;
|
||||
}
|
||||
const IsoLangEntry * findEntryById(unsigned short langId) const
|
||||
{
|
||||
static const int maxIndex = sizeof(LANG_ENTRIES)/sizeof(IsoLangEntry);
|
||||
int window = mSeedPosition;
|
||||
int guess = mSeedPosition - 1;
|
||||
while (LANG_ENTRIES[guess].mnLang != langId)
|
||||
{
|
||||
window /= 2;
|
||||
if (window == 0) return NULL;
|
||||
guess += (LANG_ENTRIES[guess].mnLang > langId)? -window : window;
|
||||
while (guess >= maxIndex)
|
||||
{
|
||||
window /= 2;
|
||||
guess -= window;
|
||||
assert(window);
|
||||
}
|
||||
}
|
||||
return &LANG_ENTRIES[guess];
|
||||
}
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
private:
|
||||
const IsoLangEntry ** mLangLookup[26][26];
|
||||
int mSeedPosition;
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
101
thirdparty/graphite/src/inc/opcode_table.h
vendored
Normal file
101
thirdparty/graphite/src/inc/opcode_table.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
// This file will be pulled into and integrated into a machine implmentation
|
||||
// DO NOT build directly
|
||||
#pragma once
|
||||
|
||||
#define do2(n) do_(n) ,do_(n)
|
||||
#define NILOP 0U
|
||||
|
||||
// types or parameters are: (.. is inclusive)
|
||||
// number - any byte
|
||||
// output_class - 0 .. silf.m_nClass
|
||||
// input_class - 0 .. silf.m_nClass
|
||||
// sattrnum - 0 .. 29 (gr_slatJWidth) , 55 (gr_slatUserDefn)
|
||||
// attrid - 0 .. silf.numUser() where sattrnum == 55; 0..silf.m_iMaxComp where sattrnum == 15 otherwise 0
|
||||
// gattrnum - 0 .. face->getGlyphFaceCache->numAttrs()
|
||||
// gmetric - 0 .. 11 (kgmetDescent)
|
||||
// featidx - 0 .. face.numFeatures()
|
||||
// level - any byte
|
||||
static const opcode_t opcode_table[] =
|
||||
{
|
||||
{{do2(nop)}, 0, "NOP"},
|
||||
|
||||
{{do2(push_byte)}, 1, "PUSH_BYTE"}, // number
|
||||
{{do2(push_byte_u)}, 1, "PUSH_BYTE_U"}, // number
|
||||
{{do2(push_short)}, 2, "PUSH_SHORT"}, // number number
|
||||
{{do2(push_short_u)}, 2, "PUSH_SHORT_U"}, // number number
|
||||
{{do2(push_long)}, 4, "PUSH_LONG"}, // number number number number
|
||||
|
||||
{{do2(add)}, 0, "ADD"},
|
||||
{{do2(sub)}, 0, "SUB"},
|
||||
{{do2(mul)}, 0, "MUL"},
|
||||
{{do2(div_)}, 0, "DIV"},
|
||||
{{do2(min_)}, 0, "MIN"},
|
||||
{{do2(max_)}, 0, "MAX"},
|
||||
{{do2(neg)}, 0, "NEG"},
|
||||
{{do2(trunc8)}, 0, "TRUNC8"},
|
||||
{{do2(trunc16)}, 0, "TRUNC16"},
|
||||
|
||||
{{do2(cond)}, 0, "COND"},
|
||||
{{do2(and_)}, 0, "AND"}, // 0x10
|
||||
{{do2(or_)}, 0, "OR"},
|
||||
{{do2(not_)}, 0, "NOT"},
|
||||
{{do2(equal)}, 0, "EQUAL"},
|
||||
{{do2(not_eq_)}, 0, "NOT_EQ"},
|
||||
{{do2(less)}, 0, "LESS"},
|
||||
{{do2(gtr)}, 0, "GTR"},
|
||||
{{do2(less_eq)}, 0, "LESS_EQ"},
|
||||
{{do2(gtr_eq)}, 0, "GTR_EQ"}, // 0x18
|
||||
|
||||
{{do_(next), NILOP}, 0, "NEXT"},
|
||||
{{NILOP, NILOP}, 1, "NEXT_N"}, // number <= smap.end - map
|
||||
{{do_(next), NILOP}, 0, "COPY_NEXT"},
|
||||
{{do_(put_glyph_8bit_obs), NILOP}, 1, "PUT_GLYPH_8BIT_OBS"}, // output_class
|
||||
{{do_(put_subs_8bit_obs), NILOP}, 3, "PUT_SUBS_8BIT_OBS"}, // slot input_class output_class
|
||||
{{do_(put_copy), NILOP}, 1, "PUT_COPY"}, // slot
|
||||
{{do_(insert), NILOP}, 0, "INSERT"},
|
||||
{{do_(delete_), NILOP}, 0, "DELETE"}, // 0x20
|
||||
{{do_(assoc), NILOP}, VARARGS, "ASSOC"},
|
||||
{{NILOP ,do_(cntxt_item)}, 2, "CNTXT_ITEM"}, // slot offset
|
||||
|
||||
{{do_(attr_set), NILOP}, 1, "ATTR_SET"}, // sattrnum
|
||||
{{do_(attr_add), NILOP}, 1, "ATTR_ADD"}, // sattrnum
|
||||
{{do_(attr_sub), NILOP}, 1, "ATTR_SUB"}, // sattrnum
|
||||
{{do_(attr_set_slot), NILOP}, 1, "ATTR_SET_SLOT"}, // sattrnum
|
||||
{{do_(iattr_set_slot), NILOP}, 2, "IATTR_SET_SLOT"}, // sattrnum attrid
|
||||
{{do2(push_slot_attr)}, 2, "PUSH_SLOT_ATTR"}, // sattrnum slot
|
||||
{{do2(push_glyph_attr_obs)}, 2, "PUSH_GLYPH_ATTR_OBS"}, // gattrnum slot
|
||||
{{do2(push_glyph_metric)}, 3, "PUSH_GLYPH_METRIC"}, // gmetric slot level
|
||||
{{do2(push_feat)}, 2, "PUSH_FEAT"}, // featidx slot
|
||||
|
||||
{{do2(push_att_to_gattr_obs)}, 2, "PUSH_ATT_TO_GATTR_OBS"}, // gattrnum slot
|
||||
{{do2(push_att_to_glyph_metric)}, 3, "PUSH_ATT_TO_GLYPH_METRIC"}, // gmetric slot level
|
||||
{{do2(push_islot_attr)}, 3, "PUSH_ISLOT_ATTR"}, // sattrnum slot attrid
|
||||
|
||||
{{NILOP,NILOP}, 3, "PUSH_IGLYPH_ATTR"},
|
||||
|
||||
{{do2(pop_ret)}, 0, "POP_RET"}, // 0x30
|
||||
{{do2(ret_zero)}, 0, "RET_ZERO"},
|
||||
{{do2(ret_true)}, 0, "RET_TRUE"},
|
||||
|
||||
{{do_(iattr_set), NILOP}, 2, "IATTR_SET"}, // sattrnum attrid
|
||||
{{do_(iattr_add), NILOP}, 2, "IATTR_ADD"}, // sattrnum attrid
|
||||
{{do_(iattr_sub), NILOP}, 2, "IATTR_SUB"}, // sattrnum attrid
|
||||
{{do2(push_proc_state)}, 1, "PUSH_PROC_STATE"}, // dummy
|
||||
{{do2(push_version)}, 0, "PUSH_VERSION"},
|
||||
{{do_(put_subs), NILOP}, 5, "PUT_SUBS"}, // slot input_class input_class output_class output_class
|
||||
{{NILOP,NILOP}, 0, "PUT_SUBS2"},
|
||||
{{NILOP,NILOP}, 0, "PUT_SUBS3"},
|
||||
{{do_(put_glyph), NILOP}, 2, "PUT_GLYPH"}, // output_class output_class
|
||||
{{do2(push_glyph_attr)}, 3, "PUSH_GLYPH_ATTR"}, // gattrnum gattrnum slot
|
||||
{{do2(push_att_to_glyph_attr)}, 3, "PUSH_ATT_TO_GLYPH_ATTR"}, // gattrnum gattrnum slot
|
||||
{{do2(bor)}, 0, "BITOR"},
|
||||
{{do2(band)}, 0, "BITAND"},
|
||||
{{do2(bnot)}, 0, "BITNOT"}, // 0x40
|
||||
{{do2(setbits)}, 4, "BITSET"},
|
||||
{{do_(set_feat), NILOP}, 2, "SET_FEAT"}, // featidx slot
|
||||
// private opcodes for internal use only, comes after all other on disk opcodes.
|
||||
{{do_(temp_copy), NILOP}, 0, "TEMP_COPY"}
|
||||
};
|
668
thirdparty/graphite/src/inc/opcodes.h
vendored
Normal file
668
thirdparty/graphite/src/inc/opcodes.h
vendored
Normal file
@@ -0,0 +1,668 @@
|
||||
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
|
||||
// Copyright 2010, SIL International, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
// This file will be pulled into and integrated into a machine implmentation
|
||||
// DO NOT build directly and under no circumstances ever #include headers in
|
||||
// here or you will break the direct_machine.
|
||||
//
|
||||
// Implementers' notes
|
||||
// ==================
|
||||
// You have access to a few primitives and the full C++ code:
|
||||
// declare_params(n) Tells the interpreter how many bytes of parameter
|
||||
// space to claim for this instruction uses and
|
||||
// initialises the param pointer. You *must* before the
|
||||
// first use of param.
|
||||
// use_params(n) Claim n extra bytes of param space beyond what was
|
||||
// claimed using delcare_param.
|
||||
// param A const byte pointer for the parameter space claimed by
|
||||
// this instruction.
|
||||
// binop(op) Implement a binary operation on the stack using the
|
||||
// specified C++ operator.
|
||||
// NOT_IMPLEMENTED Any instruction body containing this will exit the
|
||||
// program with an assertion error. Instructions that are
|
||||
// not implemented should also be marked NILOP in the
|
||||
// opcodes tables this will cause the code class to spot
|
||||
// them in a live code stream and throw a runtime_error
|
||||
// instead.
|
||||
// push(n) Push the value n onto the stack.
|
||||
// pop() Pop the top most value and return it.
|
||||
//
|
||||
// You have access to the following named fast 'registers':
|
||||
// sp = The pointer to the current top of stack, the last value
|
||||
// pushed.
|
||||
// seg = A reference to the Segment this code is running over.
|
||||
// is = The current slot index
|
||||
// isb = The original base slot index at the start of this rule
|
||||
// isf = The first positioned slot
|
||||
// isl = The last positioned slot
|
||||
// ip = The current instruction pointer
|
||||
// endPos = Position of advance of last cluster
|
||||
// dir = writing system directionality of the font
|
||||
|
||||
|
||||
// #define NOT_IMPLEMENTED assert(false)
|
||||
// #define NOT_IMPLEMENTED
|
||||
|
||||
#define binop(op) const uint32 a = pop(); *sp = uint32(*sp) op a
|
||||
#define sbinop(op) const int32 a = pop(); *sp = int32(*sp) op a
|
||||
#define use_params(n) dp += n
|
||||
|
||||
#define declare_params(n) const byte * param = dp; \
|
||||
use_params(n);
|
||||
|
||||
#define push(n) { *++sp = n; }
|
||||
#define pop() (*sp--)
|
||||
#define slotat(x) (map[(x)])
|
||||
#define DIE { is=seg.last(); status = Machine::died_early; EXIT(1); }
|
||||
#define POSITIONED 1
|
||||
|
||||
STARTOP(nop)
|
||||
do {} while (0);
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_byte)
|
||||
declare_params(1);
|
||||
push(int8(*param));
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_byte_u)
|
||||
declare_params(1);
|
||||
push(uint8(*param));
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_short)
|
||||
declare_params(2);
|
||||
const int16 r = int16(param[0]) << 8
|
||||
| uint8(param[1]);
|
||||
push(r);
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_short_u)
|
||||
declare_params(2);
|
||||
const uint16 r = uint16(param[0]) << 8
|
||||
| uint8(param[1]);
|
||||
push(r);
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_long)
|
||||
declare_params(4);
|
||||
const int32 r = int32(param[0]) << 24
|
||||
| uint32(param[1]) << 16
|
||||
| uint32(param[2]) << 8
|
||||
| uint8(param[3]);
|
||||
push(r);
|
||||
ENDOP
|
||||
|
||||
STARTOP(add)
|
||||
binop(+);
|
||||
ENDOP
|
||||
|
||||
STARTOP(sub)
|
||||
binop(-);
|
||||
ENDOP
|
||||
|
||||
STARTOP(mul)
|
||||
binop(*);
|
||||
ENDOP
|
||||
|
||||
STARTOP(div_)
|
||||
const int32 b = pop();
|
||||
const int32 a = int32(*sp);
|
||||
if (b == 0 || (a == std::numeric_limits<int32>::min() && b == -1)) DIE;
|
||||
*sp = int32(*sp) / b;
|
||||
ENDOP
|
||||
|
||||
STARTOP(min_)
|
||||
const int32 a = pop(), b = *sp;
|
||||
if (a < b) *sp = a;
|
||||
ENDOP
|
||||
|
||||
STARTOP(max_)
|
||||
const int32 a = pop(), b = *sp;
|
||||
if (a > b) *sp = a;
|
||||
ENDOP
|
||||
|
||||
STARTOP(neg)
|
||||
*sp = uint32(-int32(*sp));
|
||||
ENDOP
|
||||
|
||||
STARTOP(trunc8)
|
||||
*sp = uint8(*sp);
|
||||
ENDOP
|
||||
|
||||
STARTOP(trunc16)
|
||||
*sp = uint16(*sp);
|
||||
ENDOP
|
||||
|
||||
STARTOP(cond)
|
||||
const uint32 f = pop(), t = pop(), c = pop();
|
||||
push(c ? t : f);
|
||||
ENDOP
|
||||
|
||||
STARTOP(and_)
|
||||
binop(&&);
|
||||
ENDOP
|
||||
|
||||
STARTOP(or_)
|
||||
binop(||);
|
||||
ENDOP
|
||||
|
||||
STARTOP(not_)
|
||||
*sp = !*sp;
|
||||
ENDOP
|
||||
|
||||
STARTOP(equal)
|
||||
binop(==);
|
||||
ENDOP
|
||||
|
||||
STARTOP(not_eq_)
|
||||
binop(!=);
|
||||
ENDOP
|
||||
|
||||
STARTOP(less)
|
||||
sbinop(<);
|
||||
ENDOP
|
||||
|
||||
STARTOP(gtr)
|
||||
sbinop(>);
|
||||
ENDOP
|
||||
|
||||
STARTOP(less_eq)
|
||||
sbinop(<=);
|
||||
ENDOP
|
||||
|
||||
STARTOP(gtr_eq)
|
||||
sbinop(>=);
|
||||
ENDOP
|
||||
|
||||
STARTOP(next)
|
||||
if (map - &smap[0] >= int(smap.size())) DIE
|
||||
if (is)
|
||||
{
|
||||
if (is == smap.highwater())
|
||||
smap.highpassed(true);
|
||||
is = is->next();
|
||||
}
|
||||
++map;
|
||||
ENDOP
|
||||
|
||||
//STARTOP(next_n)
|
||||
// use_params(1);
|
||||
// NOT_IMPLEMENTED;
|
||||
//declare_params(1);
|
||||
//const size_t num = uint8(*param);
|
||||
//ENDOP
|
||||
|
||||
//STARTOP(copy_next)
|
||||
// if (is) is = is->next();
|
||||
// ++map;
|
||||
// ENDOP
|
||||
|
||||
STARTOP(put_glyph_8bit_obs)
|
||||
declare_params(1);
|
||||
const unsigned int output_class = uint8(*param);
|
||||
is->setGlyph(&seg, seg.getClassGlyph(output_class, 0));
|
||||
ENDOP
|
||||
|
||||
STARTOP(put_subs_8bit_obs)
|
||||
declare_params(3);
|
||||
const int slot_ref = int8(param[0]);
|
||||
const unsigned int input_class = uint8(param[1]),
|
||||
output_class = uint8(param[2]);
|
||||
uint16 index;
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
index = seg.findClassIndex(input_class, slot->gid());
|
||||
is->setGlyph(&seg, seg.getClassGlyph(output_class, index));
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(put_copy)
|
||||
declare_params(1);
|
||||
const int slot_ref = int8(*param);
|
||||
if (is && !is->isDeleted())
|
||||
{
|
||||
slotref ref = slotat(slot_ref);
|
||||
if (ref && ref != is)
|
||||
{
|
||||
int16 *tempUserAttrs = is->userAttrs();
|
||||
if (is->attachedTo() || is->firstChild()) DIE
|
||||
Slot *prev = is->prev();
|
||||
Slot *next = is->next();
|
||||
memcpy(tempUserAttrs, ref->userAttrs(), seg.numAttrs() * sizeof(uint16));
|
||||
memcpy(is, ref, sizeof(Slot));
|
||||
is->firstChild(NULL);
|
||||
is->nextSibling(NULL);
|
||||
is->userAttrs(tempUserAttrs);
|
||||
is->next(next);
|
||||
is->prev(prev);
|
||||
if (is->attachedTo())
|
||||
is->attachedTo()->child(is);
|
||||
}
|
||||
is->markCopied(false);
|
||||
is->markDeleted(false);
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(insert)
|
||||
if (smap.decMax() <= 0) DIE;
|
||||
Slot *newSlot = seg.newSlot();
|
||||
if (!newSlot) DIE;
|
||||
Slot *iss = is;
|
||||
while (iss && iss->isDeleted()) iss = iss->next();
|
||||
if (!iss)
|
||||
{
|
||||
if (seg.last())
|
||||
{
|
||||
seg.last()->next(newSlot);
|
||||
newSlot->prev(seg.last());
|
||||
newSlot->before(seg.last()->before());
|
||||
seg.last(newSlot);
|
||||
}
|
||||
else
|
||||
{
|
||||
seg.first(newSlot);
|
||||
seg.last(newSlot);
|
||||
}
|
||||
}
|
||||
else if (iss->prev())
|
||||
{
|
||||
iss->prev()->next(newSlot);
|
||||
newSlot->prev(iss->prev());
|
||||
newSlot->before(iss->prev()->after());
|
||||
}
|
||||
else
|
||||
{
|
||||
newSlot->prev(NULL);
|
||||
newSlot->before(iss->before());
|
||||
seg.first(newSlot);
|
||||
}
|
||||
newSlot->next(iss);
|
||||
if (iss)
|
||||
{
|
||||
iss->prev(newSlot);
|
||||
newSlot->originate(iss->original());
|
||||
newSlot->after(iss->before());
|
||||
}
|
||||
else if (newSlot->prev())
|
||||
{
|
||||
newSlot->originate(newSlot->prev()->original());
|
||||
newSlot->after(newSlot->prev()->after());
|
||||
}
|
||||
else
|
||||
{
|
||||
newSlot->originate(seg.defaultOriginal());
|
||||
}
|
||||
if (is == smap.highwater())
|
||||
smap.highpassed(false);
|
||||
is = newSlot;
|
||||
seg.extendLength(1);
|
||||
if (map != &smap[-1])
|
||||
--map;
|
||||
ENDOP
|
||||
|
||||
STARTOP(delete_)
|
||||
if (!is || is->isDeleted()) DIE
|
||||
is->markDeleted(true);
|
||||
if (is->prev())
|
||||
is->prev()->next(is->next());
|
||||
else
|
||||
seg.first(is->next());
|
||||
|
||||
if (is->next())
|
||||
is->next()->prev(is->prev());
|
||||
else
|
||||
seg.last(is->prev());
|
||||
|
||||
|
||||
if (is == smap.highwater())
|
||||
smap.highwater(is->next());
|
||||
if (is->prev())
|
||||
is = is->prev();
|
||||
seg.extendLength(-1);
|
||||
ENDOP
|
||||
|
||||
STARTOP(assoc)
|
||||
declare_params(1);
|
||||
unsigned int num = uint8(*param);
|
||||
const int8 * assocs = reinterpret_cast<const int8 *>(param+1);
|
||||
use_params(num);
|
||||
int max = -1;
|
||||
int min = -1;
|
||||
|
||||
while (num-- > 0)
|
||||
{
|
||||
int sr = *assocs++;
|
||||
slotref ts = slotat(sr);
|
||||
if (ts && (min == -1 || ts->before() < min)) min = ts->before();
|
||||
if (ts && ts->after() > max) max = ts->after();
|
||||
}
|
||||
if (min > -1) // implies max > -1
|
||||
{
|
||||
is->before(min);
|
||||
is->after(max);
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(cntxt_item)
|
||||
// It turns out this is a cunningly disguised condition forward jump.
|
||||
declare_params(3);
|
||||
const int is_arg = int8(param[0]);
|
||||
const size_t iskip = uint8(param[1]),
|
||||
dskip = uint8(param[2]);
|
||||
|
||||
if (mapb + is_arg != map)
|
||||
{
|
||||
ip += iskip;
|
||||
dp += dskip;
|
||||
push(true);
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(attr_set)
|
||||
declare_params(1);
|
||||
const attrCode slat = attrCode(uint8(*param));
|
||||
const int val = pop();
|
||||
is->setAttr(&seg, slat, 0, val, smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(attr_add)
|
||||
declare_params(1);
|
||||
const attrCode slat = attrCode(uint8(*param));
|
||||
const uint32_t val = pop();
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
uint32_t res = uint32_t(is->getAttr(&seg, slat, 0));
|
||||
is->setAttr(&seg, slat, 0, int32_t(val + res), smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(attr_sub)
|
||||
declare_params(1);
|
||||
const attrCode slat = attrCode(uint8(*param));
|
||||
const uint32_t val = pop();
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
uint32_t res = uint32_t(is->getAttr(&seg, slat, 0));
|
||||
is->setAttr(&seg, slat, 0, int32_t(res - val), smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(attr_set_slot)
|
||||
declare_params(1);
|
||||
const attrCode slat = attrCode(uint8(*param));
|
||||
const int offset = int(map - smap.begin())*int(slat == gr_slatAttTo);
|
||||
const int val = pop() + offset;
|
||||
is->setAttr(&seg, slat, offset, val, smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(iattr_set_slot)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const uint8 idx = uint8(param[1]);
|
||||
const int val = int(pop() + (map - smap.begin())*int(slat == gr_slatAttTo));
|
||||
is->setAttr(&seg, slat, idx, val, smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_slot_attr)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const int slot_ref = int8(param[1]);
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
int res = slot->getAttr(&seg, slat, 0);
|
||||
push(res);
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_glyph_attr_obs)
|
||||
declare_params(2);
|
||||
const unsigned int glyph_attr = uint8(param[0]);
|
||||
const int slot_ref = int8(param[1]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_glyph_metric)
|
||||
declare_params(3);
|
||||
const unsigned int glyph_attr = uint8(param[0]);
|
||||
const int slot_ref = int8(param[1]);
|
||||
const signed int attr_level = uint8(param[2]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
push(seg.getGlyphMetric(slot, glyph_attr, attr_level, dir));
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_feat)
|
||||
declare_params(2);
|
||||
const unsigned int feat = uint8(param[0]);
|
||||
const int slot_ref = int8(param[1]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
uint8 fid = seg.charinfo(slot->original())->fid();
|
||||
push(seg.getFeature(fid, feat));
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_att_to_gattr_obs)
|
||||
declare_params(2);
|
||||
const unsigned int glyph_attr = uint8(param[0]);
|
||||
const int slot_ref = int8(param[1]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
slotref att = slot->attachedTo();
|
||||
if (att) slot = att;
|
||||
push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_att_to_glyph_metric)
|
||||
declare_params(3);
|
||||
const unsigned int glyph_attr = uint8(param[0]);
|
||||
const int slot_ref = int8(param[1]);
|
||||
const signed int attr_level = uint8(param[2]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
slotref att = slot->attachedTo();
|
||||
if (att) slot = att;
|
||||
push(int32(seg.getGlyphMetric(slot, glyph_attr, attr_level, dir)));
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_islot_attr)
|
||||
declare_params(3);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const int slot_ref = int8(param[1]),
|
||||
idx = uint8(param[2]);
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
int res = slot->getAttr(&seg, slat, idx);
|
||||
push(res);
|
||||
}
|
||||
ENDOP
|
||||
|
||||
#if 0
|
||||
STARTOP(push_iglyph_attr) // not implemented
|
||||
NOT_IMPLEMENTED;
|
||||
ENDOP
|
||||
#endif
|
||||
|
||||
STARTOP(pop_ret)
|
||||
const uint32 ret = pop();
|
||||
EXIT(ret);
|
||||
ENDOP
|
||||
|
||||
STARTOP(ret_zero)
|
||||
EXIT(0);
|
||||
ENDOP
|
||||
|
||||
STARTOP(ret_true)
|
||||
EXIT(1);
|
||||
ENDOP
|
||||
|
||||
STARTOP(iattr_set)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const uint8 idx = uint8(param[1]);
|
||||
const int val = pop();
|
||||
is->setAttr(&seg, slat, idx, val, smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(iattr_add)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const uint8 idx = uint8(param[1]);
|
||||
const uint32_t val = pop();
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
uint32_t res = uint32_t(is->getAttr(&seg, slat, idx));
|
||||
is->setAttr(&seg, slat, idx, int32_t(val + res), smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(iattr_sub)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const uint8 idx = uint8(param[1]);
|
||||
const uint32_t val = pop();
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
uint32_t res = uint32_t(is->getAttr(&seg, slat, idx));
|
||||
is->setAttr(&seg, slat, idx, int32_t(res - val), smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_proc_state)
|
||||
use_params(1);
|
||||
push(1);
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_version)
|
||||
push(0x00030000);
|
||||
ENDOP
|
||||
|
||||
STARTOP(put_subs)
|
||||
declare_params(5);
|
||||
const int slot_ref = int8(param[0]);
|
||||
const unsigned int input_class = uint8(param[1]) << 8
|
||||
| uint8(param[2]);
|
||||
const unsigned int output_class = uint8(param[3]) << 8
|
||||
| uint8(param[4]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
int index = seg.findClassIndex(input_class, slot->gid());
|
||||
is->setGlyph(&seg, seg.getClassGlyph(output_class, index));
|
||||
}
|
||||
ENDOP
|
||||
|
||||
#if 0
|
||||
STARTOP(put_subs2) // not implemented
|
||||
NOT_IMPLEMENTED;
|
||||
ENDOP
|
||||
|
||||
STARTOP(put_subs3) // not implemented
|
||||
NOT_IMPLEMENTED;
|
||||
ENDOP
|
||||
#endif
|
||||
|
||||
STARTOP(put_glyph)
|
||||
declare_params(2);
|
||||
const unsigned int output_class = uint8(param[0]) << 8
|
||||
| uint8(param[1]);
|
||||
is->setGlyph(&seg, seg.getClassGlyph(output_class, 0));
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_glyph_attr)
|
||||
declare_params(3);
|
||||
const unsigned int glyph_attr = uint8(param[0]) << 8
|
||||
| uint8(param[1]);
|
||||
const int slot_ref = int8(param[2]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_att_to_glyph_attr)
|
||||
declare_params(3);
|
||||
const unsigned int glyph_attr = uint8(param[0]) << 8
|
||||
| uint8(param[1]);
|
||||
const int slot_ref = int8(param[2]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
slotref att = slot->attachedTo();
|
||||
if (att) slot = att;
|
||||
push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
|
||||
}
|
||||
ENDOP
|
||||
|
||||
STARTOP(temp_copy)
|
||||
slotref newSlot = seg.newSlot();
|
||||
if (!newSlot || !is) DIE;
|
||||
int16 *tempUserAttrs = newSlot->userAttrs();
|
||||
memcpy(newSlot, is, sizeof(Slot));
|
||||
memcpy(tempUserAttrs, is->userAttrs(), seg.numAttrs() * sizeof(uint16));
|
||||
newSlot->userAttrs(tempUserAttrs);
|
||||
newSlot->markCopied(true);
|
||||
*map = newSlot;
|
||||
ENDOP
|
||||
|
||||
STARTOP(band)
|
||||
binop(&);
|
||||
ENDOP
|
||||
|
||||
STARTOP(bor)
|
||||
binop(|);
|
||||
ENDOP
|
||||
|
||||
STARTOP(bnot)
|
||||
*sp = ~*sp;
|
||||
ENDOP
|
||||
|
||||
STARTOP(setbits)
|
||||
declare_params(4);
|
||||
const uint16 m = uint16(param[0]) << 8
|
||||
| uint8(param[1]);
|
||||
const uint16 v = uint16(param[2]) << 8
|
||||
| uint8(param[3]);
|
||||
*sp = ((*sp) & ~m) | v;
|
||||
ENDOP
|
||||
|
||||
STARTOP(set_feat)
|
||||
declare_params(2);
|
||||
const unsigned int feat = uint8(param[0]);
|
||||
const int slot_ref = int8(param[1]);
|
||||
slotref slot = slotat(slot_ref);
|
||||
if (slot)
|
||||
{
|
||||
uint8 fid = seg.charinfo(slot->original())->fid();
|
||||
seg.setFeature(fid, feat, pop());
|
||||
}
|
||||
ENDOP
|
Reference in New Issue
Block a user