Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/graphite/src/inc/Collider.h
9906 views
1
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
2
// Copyright 2010, SIL International, All rights reserved.
3
4
#pragma once
5
6
#include "inc/List.h"
7
#include "inc/Position.h"
8
#include "inc/Intervals.h"
9
#include "inc/debug.h"
10
11
namespace graphite2 {
12
13
class json;
14
class Slot;
15
class Segment;
16
17
#define SLOTCOLSETUINTPROP(x, y) uint16 x() const { return _ ##x; } void y (uint16 v) { _ ##x = v; }
18
#define SLOTCOLSETINTPROP(x, y) int16 x() const { return _ ##x; } void y (int16 v) { _ ##x = v; }
19
#define SLOTCOLSETPOSITIONPROP(x, y) const Position &x() const { return _ ##x; } void y (const Position &v) { _ ##x = v; }
20
21
// Slot attributes related to collision-fixing
22
class SlotCollision
23
{
24
public:
25
enum {
26
// COLL_TESTONLY = 0, // default - test other glyphs for collision with this one, but don't move this one
27
COLL_FIX = 1, // fix collisions involving this glyph
28
COLL_IGNORE = 2, // ignore this glyph altogether
29
COLL_START = 4, // start of range of possible collisions
30
COLL_END = 8, // end of range of possible collisions
31
COLL_KERN = 16, // collisions with this glyph are fixed by adding kerning space after it
32
COLL_ISCOL = 32, // this glyph has a collision
33
COLL_KNOWN = 64, // we've figured out what's happening with this glyph
34
COLL_ISSPACE = 128, // treat this glyph as a space with regard to kerning
35
COLL_TEMPLOCK = 256, // Lock glyphs that have been given priority positioning
36
////COLL_JUMPABLE = 128, // moving glyphs may jump this stationary glyph in any direction - DELETE
37
////COLL_OVERLAP = 256, // use maxoverlap to restrict - DELETE
38
};
39
40
// Behavior for the collision.order attribute. To GDL this is an enum, to us it's a bitfield, with only 1 bit set
41
// Allows for easier inversion.
42
enum {
43
SEQ_ORDER_LEFTDOWN = 1,
44
SEQ_ORDER_RIGHTUP = 2,
45
SEQ_ORDER_NOABOVE = 4,
46
SEQ_ORDER_NOBELOW = 8,
47
SEQ_ORDER_NOLEFT = 16,
48
SEQ_ORDER_NORIGHT = 32
49
};
50
51
SlotCollision(Segment *seg, Slot *slot);
52
void initFromSlot(Segment *seg, Slot *slot);
53
54
const Rect &limit() const { return _limit; }
55
void setLimit(const Rect &r) { _limit = r; }
56
SLOTCOLSETPOSITIONPROP(shift, setShift)
57
SLOTCOLSETPOSITIONPROP(offset, setOffset)
58
SLOTCOLSETPOSITIONPROP(exclOffset, setExclOffset)
59
SLOTCOLSETUINTPROP(margin, setMargin)
60
SLOTCOLSETUINTPROP(marginWt, setMarginWt)
61
SLOTCOLSETUINTPROP(flags, setFlags)
62
SLOTCOLSETUINTPROP(exclGlyph, setExclGlyph)
63
SLOTCOLSETUINTPROP(seqClass, setSeqClass)
64
SLOTCOLSETUINTPROP(seqProxClass, setSeqProxClass)
65
SLOTCOLSETUINTPROP(seqOrder, setSeqOrder)
66
SLOTCOLSETINTPROP(seqAboveXoff, setSeqAboveXoff)
67
SLOTCOLSETUINTPROP(seqAboveWt, setSeqAboveWt)
68
SLOTCOLSETINTPROP(seqBelowXlim, setSeqBelowXlim)
69
SLOTCOLSETUINTPROP(seqBelowWt, setSeqBelowWt)
70
SLOTCOLSETUINTPROP(seqValignHt, setSeqValignHt)
71
SLOTCOLSETUINTPROP(seqValignWt, setSeqValignWt)
72
73
float getKern(int dir) const;
74
bool ignore() const;
75
76
private:
77
Rect _limit;
78
Position _shift; // adjustment within the given pass
79
Position _offset; // total adjustment for collisions
80
Position _exclOffset;
81
uint16 _margin;
82
uint16 _marginWt;
83
uint16 _flags;
84
uint16 _exclGlyph;
85
uint16 _seqClass;
86
uint16 _seqProxClass;
87
uint16 _seqOrder;
88
int16 _seqAboveXoff;
89
uint16 _seqAboveWt;
90
int16 _seqBelowXlim;
91
uint16 _seqBelowWt;
92
uint16 _seqValignHt;
93
uint16 _seqValignWt;
94
95
}; // end of class SlotColllision
96
97
struct BBox;
98
struct SlantBox;
99
100
class ShiftCollider
101
{
102
public:
103
typedef std::pair<float, float> fpair;
104
typedef Vector<fpair> vfpairs;
105
typedef vfpairs::iterator ivfpairs;
106
107
ShiftCollider(json *dbgout);
108
~ShiftCollider() throw() { };
109
110
bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint,
111
float margin, float marginMin, const Position &currShift,
112
const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout);
113
bool mergeSlot(Segment *seg, Slot *slot, const SlotCollision *cinfo, const Position &currShift, bool isAfter,
114
bool sameCluster, bool &hasCol, bool isExclusion, GR_MAYBE_UNUSED json * const dbgout);
115
Position resolve(Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout);
116
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);
117
void removeBox(const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, int mode);
118
const Position &origin() const { return _origin; }
119
120
#if !defined GRAPHITE2_NTRACING
121
void outputJsonDbg(json * const dbgout, Segment *seg, int axis);
122
void outputJsonDbgStartSlot(json * const dbgout, Segment *seg);
123
void outputJsonDbgEndSlot(json * const dbgout, Position resultPos, int bestAxis, bool isCol);
124
void outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis, float tleft, float bestCost, float bestVal);
125
void outputJsonDbgRawRanges(json * const dbgout, int axis);
126
void outputJsonDbgRemovals(json * const dbgout, int axis, Segment *seg);
127
#endif
128
129
CLASS_NEW_DELETE;
130
131
protected:
132
Zones _ranges[4]; // possible movements in 4 directions (horizontally, vertically, diagonally);
133
Slot * _target; // the glyph to fix
134
Rect _limit;
135
Position _currShift;
136
Position _currOffset;
137
Position _origin; // Base for all relative calculations
138
float _margin;
139
float _marginWt;
140
float _len[4];
141
uint16 _seqClass;
142
uint16 _seqProxClass;
143
uint16 _seqOrder;
144
145
//bool _scraping[4];
146
147
}; // end of class ShiftCollider
148
149
inline
150
ShiftCollider::ShiftCollider(GR_MAYBE_UNUSED json *dbgout)
151
: _target(0),
152
_margin(0.0),
153
_marginWt(0.0),
154
_seqClass(0),
155
_seqProxClass(0),
156
_seqOrder(0)
157
{
158
#if !defined GRAPHITE2_NTRACING
159
for (int i = 0; i < 4; ++i)
160
_ranges[i].setdebug(dbgout);
161
#endif
162
}
163
164
class KernCollider
165
{
166
public:
167
KernCollider(json *dbg);
168
~KernCollider() throw() { };
169
bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint, float margin,
170
const Position &currShift, const Position &offsetPrev, int dir,
171
float ymin, float ymax, json * const dbgout);
172
bool mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, json * const dbgout);
173
Position resolve(Segment *seg, Slot *slot, int dir, json * const dbgout);
174
void shift(const Position &mv, int dir);
175
176
CLASS_NEW_DELETE;
177
178
private:
179
Slot * _target; // the glyph to fix
180
Rect _limit;
181
float _margin;
182
Position _offsetPrev; // kern from a previous pass
183
Position _currShift; // NOT USED??
184
float _miny; // y-coordinates offset by global slot position
185
float _maxy;
186
Vector<float> _edges; // edges of horizontal slices
187
float _sliceWidth; // width of each slice
188
float _mingap;
189
float _xbound; // max or min edge
190
bool _hit;
191
192
#if !defined GRAPHITE2_NTRACING
193
// Debugging
194
Segment * _seg;
195
Vector<float> _nearEdges; // closest potential collision in each slice
196
Vector<Slot*> _slotNear;
197
#endif
198
}; // end of class KernCollider
199
200
201
inline
202
float sqr(float x) {
203
return x * x;
204
}
205
206
inline
207
KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg)
208
: _target(0),
209
_margin(0.0f),
210
_miny(-1e38f),
211
_maxy(1e38f),
212
_sliceWidth(0.0f),
213
_mingap(0.0f),
214
_xbound(0.0),
215
_hit(false)
216
{
217
#if !defined GRAPHITE2_NTRACING
218
_seg = 0;
219
#endif
220
};
221
222
}; // end of namespace graphite2
223
224