Path: blob/master/thirdparty/graphite/src/inc/Collider.h
9906 views
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later1// Copyright 2010, SIL International, All rights reserved.23#pragma once45#include "inc/List.h"6#include "inc/Position.h"7#include "inc/Intervals.h"8#include "inc/debug.h"910namespace graphite2 {1112class json;13class Slot;14class Segment;1516#define SLOTCOLSETUINTPROP(x, y) uint16 x() const { return _ ##x; } void y (uint16 v) { _ ##x = v; }17#define SLOTCOLSETINTPROP(x, y) int16 x() const { return _ ##x; } void y (int16 v) { _ ##x = v; }18#define SLOTCOLSETPOSITIONPROP(x, y) const Position &x() const { return _ ##x; } void y (const Position &v) { _ ##x = v; }1920// Slot attributes related to collision-fixing21class SlotCollision22{23public:24enum {25// COLL_TESTONLY = 0, // default - test other glyphs for collision with this one, but don't move this one26COLL_FIX = 1, // fix collisions involving this glyph27COLL_IGNORE = 2, // ignore this glyph altogether28COLL_START = 4, // start of range of possible collisions29COLL_END = 8, // end of range of possible collisions30COLL_KERN = 16, // collisions with this glyph are fixed by adding kerning space after it31COLL_ISCOL = 32, // this glyph has a collision32COLL_KNOWN = 64, // we've figured out what's happening with this glyph33COLL_ISSPACE = 128, // treat this glyph as a space with regard to kerning34COLL_TEMPLOCK = 256, // Lock glyphs that have been given priority positioning35////COLL_JUMPABLE = 128, // moving glyphs may jump this stationary glyph in any direction - DELETE36////COLL_OVERLAP = 256, // use maxoverlap to restrict - DELETE37};3839// Behavior for the collision.order attribute. To GDL this is an enum, to us it's a bitfield, with only 1 bit set40// Allows for easier inversion.41enum {42SEQ_ORDER_LEFTDOWN = 1,43SEQ_ORDER_RIGHTUP = 2,44SEQ_ORDER_NOABOVE = 4,45SEQ_ORDER_NOBELOW = 8,46SEQ_ORDER_NOLEFT = 16,47SEQ_ORDER_NORIGHT = 3248};4950SlotCollision(Segment *seg, Slot *slot);51void initFromSlot(Segment *seg, Slot *slot);5253const Rect &limit() const { return _limit; }54void setLimit(const Rect &r) { _limit = r; }55SLOTCOLSETPOSITIONPROP(shift, setShift)56SLOTCOLSETPOSITIONPROP(offset, setOffset)57SLOTCOLSETPOSITIONPROP(exclOffset, setExclOffset)58SLOTCOLSETUINTPROP(margin, setMargin)59SLOTCOLSETUINTPROP(marginWt, setMarginWt)60SLOTCOLSETUINTPROP(flags, setFlags)61SLOTCOLSETUINTPROP(exclGlyph, setExclGlyph)62SLOTCOLSETUINTPROP(seqClass, setSeqClass)63SLOTCOLSETUINTPROP(seqProxClass, setSeqProxClass)64SLOTCOLSETUINTPROP(seqOrder, setSeqOrder)65SLOTCOLSETINTPROP(seqAboveXoff, setSeqAboveXoff)66SLOTCOLSETUINTPROP(seqAboveWt, setSeqAboveWt)67SLOTCOLSETINTPROP(seqBelowXlim, setSeqBelowXlim)68SLOTCOLSETUINTPROP(seqBelowWt, setSeqBelowWt)69SLOTCOLSETUINTPROP(seqValignHt, setSeqValignHt)70SLOTCOLSETUINTPROP(seqValignWt, setSeqValignWt)7172float getKern(int dir) const;73bool ignore() const;7475private:76Rect _limit;77Position _shift; // adjustment within the given pass78Position _offset; // total adjustment for collisions79Position _exclOffset;80uint16 _margin;81uint16 _marginWt;82uint16 _flags;83uint16 _exclGlyph;84uint16 _seqClass;85uint16 _seqProxClass;86uint16 _seqOrder;87int16 _seqAboveXoff;88uint16 _seqAboveWt;89int16 _seqBelowXlim;90uint16 _seqBelowWt;91uint16 _seqValignHt;92uint16 _seqValignWt;9394}; // end of class SlotColllision9596struct BBox;97struct SlantBox;9899class ShiftCollider100{101public:102typedef std::pair<float, float> fpair;103typedef Vector<fpair> vfpairs;104typedef vfpairs::iterator ivfpairs;105106ShiftCollider(json *dbgout);107~ShiftCollider() throw() { };108109bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint,110float margin, float marginMin, const Position &currShift,111const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout);112bool mergeSlot(Segment *seg, Slot *slot, const SlotCollision *cinfo, const Position &currShift, bool isAfter,113bool sameCluster, bool &hasCol, bool isExclusion, GR_MAYBE_UNUSED json * const dbgout);114Position resolve(Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout);115void addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int mode);116void removeBox(const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, int mode);117const Position &origin() const { return _origin; }118119#if !defined GRAPHITE2_NTRACING120void outputJsonDbg(json * const dbgout, Segment *seg, int axis);121void outputJsonDbgStartSlot(json * const dbgout, Segment *seg);122void outputJsonDbgEndSlot(json * const dbgout, Position resultPos, int bestAxis, bool isCol);123void outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis, float tleft, float bestCost, float bestVal);124void outputJsonDbgRawRanges(json * const dbgout, int axis);125void outputJsonDbgRemovals(json * const dbgout, int axis, Segment *seg);126#endif127128CLASS_NEW_DELETE;129130protected:131Zones _ranges[4]; // possible movements in 4 directions (horizontally, vertically, diagonally);132Slot * _target; // the glyph to fix133Rect _limit;134Position _currShift;135Position _currOffset;136Position _origin; // Base for all relative calculations137float _margin;138float _marginWt;139float _len[4];140uint16 _seqClass;141uint16 _seqProxClass;142uint16 _seqOrder;143144//bool _scraping[4];145146}; // end of class ShiftCollider147148inline149ShiftCollider::ShiftCollider(GR_MAYBE_UNUSED json *dbgout)150: _target(0),151_margin(0.0),152_marginWt(0.0),153_seqClass(0),154_seqProxClass(0),155_seqOrder(0)156{157#if !defined GRAPHITE2_NTRACING158for (int i = 0; i < 4; ++i)159_ranges[i].setdebug(dbgout);160#endif161}162163class KernCollider164{165public:166KernCollider(json *dbg);167~KernCollider() throw() { };168bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint, float margin,169const Position &currShift, const Position &offsetPrev, int dir,170float ymin, float ymax, json * const dbgout);171bool mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, json * const dbgout);172Position resolve(Segment *seg, Slot *slot, int dir, json * const dbgout);173void shift(const Position &mv, int dir);174175CLASS_NEW_DELETE;176177private:178Slot * _target; // the glyph to fix179Rect _limit;180float _margin;181Position _offsetPrev; // kern from a previous pass182Position _currShift; // NOT USED??183float _miny; // y-coordinates offset by global slot position184float _maxy;185Vector<float> _edges; // edges of horizontal slices186float _sliceWidth; // width of each slice187float _mingap;188float _xbound; // max or min edge189bool _hit;190191#if !defined GRAPHITE2_NTRACING192// Debugging193Segment * _seg;194Vector<float> _nearEdges; // closest potential collision in each slice195Vector<Slot*> _slotNear;196#endif197}; // end of class KernCollider198199200inline201float sqr(float x) {202return x * x;203}204205inline206KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg)207: _target(0),208_margin(0.0f),209_miny(-1e38f),210_maxy(1e38f),211_sliceWidth(0.0f),212_mingap(0.0f),213_xbound(0.0),214_hit(false)215{216#if !defined GRAPHITE2_NTRACING217_seg = 0;218#endif219};220221}; // end of namespace graphite2222223224