diff options
Diffstat (limited to 'Build/source/libs/graphite2/graphite2-src/src/Justifier.cpp')
-rw-r--r-- | Build/source/libs/graphite2/graphite2-src/src/Justifier.cpp | 282 |
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); -} |