summaryrefslogtreecommitdiffstats
path: root/gfx/graphite2/src/inc/Collider.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/graphite2/src/inc/Collider.h')
-rw-r--r--gfx/graphite2/src/inc/Collider.h245
1 files changed, 245 insertions, 0 deletions
diff --git a/gfx/graphite2/src/inc/Collider.h b/gfx/graphite2/src/inc/Collider.h
new file mode 100644
index 0000000000..71e8400501
--- /dev/null
+++ b/gfx/graphite2/src/inc/Collider.h
@@ -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