You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-28 16:07:14 +00:00
[Complex Text Layouts] Add third-party TextServer dependencies (ICU, HarfBuzz, Graphite).
This commit is contained in:
245
thirdparty/graphite/src/inc/Collider.h
vendored
Normal file
245
thirdparty/graphite/src/inc/Collider.h
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
#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
|
||||
Reference in New Issue
Block a user