Path: blob/master/thirdparty/graphite/src/inc/Intervals.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 <utility>67#include "inc/Main.h"8#include "inc/List.h"9#include "inc/json.h"10#include "inc/Position.h"1112// An IntervalSet represents the possible movement of a given glyph in a given direction13// (horizontally, vertically, or diagonally).14// A vector is needed to represent disjoint ranges, eg, -300..-150, 20..200, 500..750.15// Each pair represents the min/max of a sub-range.1617namespace graphite2 {1819class Segment;2021enum zones_t {SD, XY};2223class Zones24{25struct Exclusion26{27template<zones_t O>28static Exclusion weighted(float xmin, float xmax, float f, float a0,29float m, float xi, float ai, float c, bool nega);3031float x, // x position32xm, // xmax position33c, // constant + sum(MiXi^2)34sm, // sum(Mi)35smx; // sum(MiXi)36bool open;3738Exclusion(float x, float w, float smi, float smxi, float c);39Exclusion & operator += (Exclusion const & rhs);40uint8 outcode(float p) const;4142Exclusion split_at(float p);43void left_trim(float p);4445bool track_cost(float & cost, float & x, float origin) const;4647private:48float test_position(float origin) const;49float cost(float x) const;50};5152typedef Vector<Exclusion> exclusions;5354typedef exclusions::iterator iterator;55typedef Exclusion * pointer;56typedef Exclusion & reference;57typedef std::reverse_iterator<iterator> reverse_iterator;5859public:60typedef exclusions::const_iterator const_iterator;61typedef Exclusion const * const_pointer;62typedef Exclusion const & const_reference;63typedef std::reverse_iterator<const_iterator> const_reverse_iterator;6465#if !defined GRAPHITE2_NTRACING66struct Debug67{68Exclusion _excl;69bool _isdel;70Vector<void *> _env;7172Debug(Exclusion *e, bool isdel, json *dbg) : _excl(*e), _isdel(isdel), _env(dbg->getenvs()) { };73};7475typedef Vector<Debug> debugs;76typedef debugs::const_iterator idebugs;77void addDebug(Exclusion *e);78void removeDebug(float pos, float posm);79void setdebug(json *dbgout) { _dbg = dbgout; }80idebugs dbgs_begin() const { return _dbgs.begin(); }81idebugs dbgs_end() const { return _dbgs.end(); }82void jsonDbgOut(Segment *seg) const;83Position position() const { return Position(_pos, _posm); }84#endif8586Zones();87template<zones_t O>88void initialise(float xmin, float xmax, float margin_len, float margin_weight, float ao);8990void exclude(float xmin, float xmax);91void exclude_with_margins(float xmin, float xmax, int axis);9293template<zones_t O>94void weighted(float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);95void weightedAxis(int axis, float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);9697float closest( float origin, float &cost) const;9899const_iterator begin() const { return _exclusions.begin(); }100const_iterator end() const { return _exclusions.end(); }101102private:103exclusions _exclusions;104#if !defined GRAPHITE2_NTRACING105json * _dbg;106debugs _dbgs;107#endif108float _margin_len,109_margin_weight,110_pos,111_posm;112113void insert(Exclusion e);114void remove(float x, float xm);115const_iterator find_exclusion_under(float x) const;116};117118119inline120Zones::Zones()121: _margin_len(0), _margin_weight(0), _pos(0), _posm(0)122{123#if !defined GRAPHITE2_NTRACING124_dbg = 0;125#endif126_exclusions.reserve(8);127}128129inline130Zones::Exclusion::Exclusion(float x_, float xm_, float smi, float smxi, float c_)131: x(x_), xm(xm_), c(c_), sm(smi), smx(smxi), open(false)132{ }133134template<zones_t O>135inline136void Zones::initialise(float xmin, float xmax, float margin_len,137float margin_weight, float a0)138{139_margin_len = margin_len;140_margin_weight = margin_weight;141_pos = xmin;142_posm = xmax;143_exclusions.clear();144_exclusions.push_back(Exclusion::weighted<O>(xmin, xmax, 1, a0, 0, 0, 0, 0, false));145_exclusions.front().open = true;146#if !defined GRAPHITE2_NTRACING147_dbgs.clear();148#endif149}150151inline152void Zones::exclude(float xmin, float xmax) {153remove(xmin, xmax);154}155156template<zones_t O>157inline158void Zones::weighted(float xmin, float xmax, float f, float a0,159float m, float xi, float ai, float c, bool nega) {160insert(Exclusion::weighted<O>(xmin, xmax, f, a0, m, xi, ai, c, nega));161}162163inline164void Zones::weightedAxis(int axis, float xmin, float xmax, float f, float a0,165float m, float xi, float ai, float c, bool nega) {166if (axis < 2)167weighted<XY>(xmin, xmax, f, a0, m, xi, ai, c, nega);168else169weighted<SD>(xmin, xmax, f, a0, m, xi, ai, c, nega);170}171172#if !defined GRAPHITE2_NTRACING173inline174void Zones::addDebug(Exclusion *e) {175if (_dbg)176_dbgs.push_back(Debug(e, false, _dbg));177}178179inline180void Zones::removeDebug(float pos, float posm) {181if (_dbg)182{183Exclusion e(pos, posm, 0, 0, 0);184_dbgs.push_back(Debug(&e, true, _dbg));185}186}187#endif188189template<>190inline191Zones::Exclusion Zones::Exclusion::weighted<XY>(float xmin, float xmax, float f, float a0,192float m, float xi, GR_MAYBE_UNUSED float ai, float c, GR_MAYBE_UNUSED bool nega) {193return Exclusion(xmin, xmax,194m + f,195m * xi,196m * xi * xi + f * a0 * a0 + c);197}198199template<>200inline201Zones::Exclusion Zones::Exclusion::weighted<SD>(float xmin, float xmax, float f, float a0,202float m, float xi, float ai,float c, bool nega) {203float xia = nega ? xi - ai : xi + ai;204return Exclusion(xmin, xmax,2050.25f * (m + 2.f * f),2060.25f * m * xia,2070.25f * (m * xia * xia + 2.f * f * a0 * a0) + c);208}209210} // end of namespace graphite2211212213