summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite2/graphite2-src/src/Justifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/graphite2/graphite2-src/src/Justifier.cpp')
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Justifier.cpp282
1 files changed, 0 insertions, 282 deletions
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Justifier.cpp b/Build/source/libs/graphite2/graphite2-src/src/Justifier.cpp
deleted file mode 100644
index 78c11e6a516..00000000000
--- a/Build/source/libs/graphite2/graphite2-src/src/Justifier.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2012, 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.
-*/
-
-#include "inc/Segment.h"
-#include "graphite2/Font.h"
-#include "inc/debug.h"
-#include "inc/CharInfo.h"
-#include "inc/Slot.h"
-#include "inc/Main.h"
-#include <cmath>
-
-using namespace graphite2;
-
-class JustifyTotal {
-public:
- JustifyTotal() : m_numGlyphs(0), m_tStretch(0), m_tShrink(0), m_tStep(0), m_tWeight(0) {}
- void accumulate(Slot *s, Segment *seg, int level);
- int weight() const { return m_tWeight; }
-
- CLASS_NEW_DELETE
-
-private:
- int m_numGlyphs;
- int m_tStretch;
- int m_tShrink;
- int m_tStep;
- int m_tWeight;
-};
-
-void JustifyTotal::accumulate(Slot *s, Segment *seg, int level)
-{
- ++m_numGlyphs;
- m_tStretch += s->getJustify(seg, level, 0);
- m_tShrink += s->getJustify(seg, level, 1);
- m_tStep += s->getJustify(seg, level, 2);
- m_tWeight += s->getJustify(seg, level, 3);
-}
-
-float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUSED justFlags jflags, Slot *pFirst, Slot *pLast)
-{
- Slot *end = last();
- float currWidth = 0.0;
- const float scale = font ? font->scale() : 1.0f;
- Position res;
-
- if (width < 0 && !(silf()->flags()))
- return width;
-
- if ((m_dir & 1) != m_silf->dir() && m_silf->bidiPass() != m_silf->numPasses())
- {
- reverseSlots();
- std::swap(pFirst, pLast);
- }
- if (!pFirst) pFirst = pSlot;
- while (!pFirst->isBase()) pFirst = pFirst->attachedTo();
- if (!pLast) pLast = last();
- while (!pLast->isBase()) pLast = pLast->attachedTo();
- const float base = pFirst->origin().x / scale;
- width = width / scale;
- if ((jflags & gr_justEndInline) == 0)
- {
- while (pLast != pFirst && pLast)
- {
- Rect bbox = theGlyphBBoxTemporary(pLast->glyph());
- if (bbox.bl.x != 0.f || bbox.bl.y != 0.f || bbox.tr.x != 0.f || bbox.tr.y == 0.f)
- break;
- pLast = pLast->prev();
- }
- }
-
- if (pLast)
- end = pLast->nextSibling();
- if (pFirst)
- pFirst = pFirst->nextSibling();
-
- int icount = 0;
- int numLevels = silf()->numJustLevels();
- if (!numLevels)
- {
- for (Slot *s = pSlot; s && s != end; s = s->nextSibling())
- {
- CharInfo *c = charinfo(s->before());
- if (isWhitespace(c->unicodeChar()))
- {
- s->setJustify(this, 0, 3, 1);
- s->setJustify(this, 0, 2, 1);
- s->setJustify(this, 0, 0, -1);
- ++icount;
- }
- }
- if (!icount)
- {
- for (Slot *s = pSlot; s && s != end; s = s->nextSibling())
- {
- s->setJustify(this, 0, 3, 1);
- s->setJustify(this, 0, 2, 1);
- s->setJustify(this, 0, 0, -1);
- }
- }
- ++numLevels;
- }
-
- Vector<JustifyTotal> stats(numLevels);
- for (Slot *s = pFirst; s && s != end; s = s->nextSibling())
- {
- float w = s->origin().x / scale + s->advance() - base;
- if (w > currWidth) currWidth = w;
- for (int j = 0; j < numLevels; ++j)
- stats[j].accumulate(s, this, j);
- s->just(0);
- }
-
- for (int i = (width < 0.0f) ? -1 : numLevels - 1; i >= 0; --i)
- {
- float diff;
- float error = 0.;
- float diffpw;
- int tWeight = stats[i].weight();
- if (tWeight == 0) continue;
-
- do {
- error = 0.;
- diff = width - currWidth;
- diffpw = diff / tWeight;
- tWeight = 0;
- for (Slot *s = pFirst; s && s != end; s = s->nextSibling()) // don't include final glyph
- {
- int w = s->getJustify(this, i, 3);
- float pref = diffpw * w + error;
- int step = s->getJustify(this, i, 2);
- if (!step) step = 1; // handle lazy font developers
- if (pref > 0)
- {
- float max = uint16(s->getJustify(this, i, 0));
- if (i == 0) max -= s->just();
- if (pref > max) pref = max;
- else tWeight += w;
- }
- else
- {
- float max = uint16(s->getJustify(this, i, 1));
- if (i == 0) max += s->just();
- if (-pref > max) pref = -max;
- else tWeight += w;
- }
- int actual = int(pref / step) * step;
-
- if (actual)
- {
- error += diffpw * w - actual;
- if (i == 0)
- s->just(s->just() + actual);
- else
- s->setJustify(this, i, 4, actual);
- }
- }
- currWidth += diff - error;
- } while (i == 0 && int(std::abs(error)) > 0 && tWeight);
- }
-
- Slot *oldFirst = m_first;
- Slot *oldLast = m_last;
- if (silf()->flags() & 1)
- {
- m_first = pSlot = addLineEnd(pSlot);
- m_last = pLast = addLineEnd(end);
- if (!m_first || !m_last) return -1.0;
- }
- else
- {
- m_first = pSlot;
- m_last = pLast;
- }
-
- // run justification passes here
-#if !defined GRAPHITE2_NTRACING
- json * const dbgout = m_face->logger();
- if (dbgout)
- *dbgout << json::object
- << "justifies" << objectid(this)
- << "passes" << json::array;
-#endif
-
- if (m_silf->justificationPass() != m_silf->positionPass() && (width >= 0.f || (silf()->flags() & 1)))
- m_silf->runGraphite(this, m_silf->justificationPass(), m_silf->positionPass());
-
-#if !defined GRAPHITE2_NTRACING
- if (dbgout)
- {
- *dbgout << json::item << json::close; // Close up the passes array
- positionSlots(NULL, pSlot, pLast, m_dir);
- Slot *lEnd = pLast->nextSibling();
- *dbgout << "output" << json::array;
- for(Slot * t = pSlot; t != lEnd; t = t->next())
- *dbgout << dslot(this, t);
- *dbgout << json::close << json::close;
- }
-#endif
-
- res = positionSlots(font, pSlot, pLast, m_dir);
-
- if (silf()->flags() & 1)
- {
- if (m_first)
- delLineEnd(m_first);
- if (m_last)
- delLineEnd(m_last);
- }
- m_first = oldFirst;
- m_last = oldLast;
-
- if ((m_dir & 1) != m_silf->dir() && m_silf->bidiPass() != m_silf->numPasses())
- reverseSlots();
- return res.x;
-}
-
-Slot *Segment::addLineEnd(Slot *nSlot)
-{
- Slot *eSlot = newSlot();
- if (!eSlot) return NULL;
- const uint16 gid = silf()->endLineGlyphid();
- const GlyphFace * theGlyph = m_face->glyphs().glyphSafe(gid);
- eSlot->setGlyph(this, gid, theGlyph);
- if (nSlot)
- {
- eSlot->next(nSlot);
- eSlot->prev(nSlot->prev());
- nSlot->prev(eSlot);
- eSlot->before(nSlot->before());
- if (eSlot->prev())
- eSlot->after(eSlot->prev()->after());
- else
- eSlot->after(nSlot->before());
- }
- else
- {
- nSlot = m_last;
- eSlot->prev(nSlot);
- nSlot->next(eSlot);
- eSlot->after(eSlot->prev()->after());
- eSlot->before(nSlot->after());
- }
- return eSlot;
-}
-
-void Segment::delLineEnd(Slot *s)
-{
- Slot *nSlot = s->next();
- if (nSlot)
- {
- nSlot->prev(s->prev());
- if (s->prev())
- s->prev()->next(nSlot);
- }
- else
- s->prev()->next(NULL);
- freeSlot(s);
-}