tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Segment.h (9573B)


      1 /*  GRAPHITE2 LICENSING
      2 
      3    Copyright 2010, SIL International
      4    All rights reserved.
      5 
      6    This library is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU Lesser General Public License as published
      8    by the Free Software Foundation; either version 2.1 of License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14    Lesser General Public License for more details.
     15 
     16    You should also have received a copy of the GNU Lesser General Public
     17    License along with this library in the file named "LICENSE".
     18    If not, write to the Free Software Foundation, 51 Franklin Street,
     19    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
     20    internet at http://www.fsf.org/licenses/lgpl.html.
     21 
     22 Alternatively, the contents of this file may be used under the terms of the
     23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
     24 License, as published by the Free Software Foundation, either version 2
     25 of the License or (at your option) any later version.
     26 */
     27 #pragma once
     28 
     29 #include "inc/Main.h"
     30 
     31 #include <cassert>
     32 
     33 #include "inc/CharInfo.h"
     34 #include "inc/Face.h"
     35 #include "inc/FeatureVal.h"
     36 #include "inc/GlyphCache.h"
     37 #include "inc/GlyphFace.h"
     38 #include "inc/Slot.h"
     39 #include "inc/Position.h"
     40 #include "inc/List.h"
     41 #include "inc/Collider.h"
     42 
     43 #define MAX_SEG_GROWTH_FACTOR  64
     44 
     45 namespace graphite2 {
     46 
     47 typedef Vector<Features>        FeatureList;
     48 typedef Vector<Slot *>          SlotRope;
     49 typedef Vector<int16 *>         AttributeRope;
     50 typedef Vector<SlotJustify *>   JustifyRope;
     51 
     52 class Font;
     53 class Segment;
     54 class Silf;
     55 
     56 enum SpliceParam {
     57 /** sub-Segments longer than this are not cached
     58 * (in Unicode code points) */
     59    eMaxSpliceSize = 96
     60 };
     61 
     62 enum justFlags {
     63    gr_justStartInline = 1,
     64    gr_justEndInline = 2
     65 };
     66 
     67 class SegmentScopeState
     68 {
     69 private:
     70    friend class Segment;
     71    Slot * realFirstSlot;
     72    Slot * slotBeforeScope;
     73    Slot * slotAfterScope;
     74    Slot * realLastSlot;
     75    size_t numGlyphsOutsideScope;
     76 };
     77 
     78 class Segment
     79 {
     80    // Prevent copying of any kind.
     81    Segment(const Segment&);
     82    Segment& operator=(const Segment&);
     83 
     84 public:
     85 
     86    enum {
     87        SEG_INITCOLLISIONS = 1,
     88        SEG_HASCOLLISIONS = 2
     89    };
     90 
     91    size_t slotCount() const { return m_numGlyphs; }      //one slot per glyph
     92    void extendLength(ptrdiff_t num) { m_numGlyphs += num; }
     93    Position advance() const { return m_advance; }
     94    bool runGraphite() { if (m_silf) return m_face->runGraphite(this, m_silf); else return true;};
     95    void chooseSilf(uint32 script) { m_silf = m_face->chooseSilf(script); }
     96    const Silf *silf() const { return m_silf; }
     97    size_t charInfoCount() const { return m_numCharinfo; }
     98    const CharInfo *charinfo(unsigned int index) const { return index < m_numCharinfo ? m_charinfo + index : NULL; }
     99    CharInfo *charinfo(unsigned int index) { return index < m_numCharinfo ? m_charinfo + index : NULL; }
    100 
    101    Segment(size_t numchars, const Face* face, uint32 script, int dir);
    102    ~Segment();
    103    uint8 flags() const { return m_flags; }
    104    void flags(uint8 f) { m_flags = f; }
    105    Slot *first() { return m_first; }
    106    void first(Slot *p) { m_first = p; }
    107    Slot *last() { return m_last; }
    108    void last(Slot *p) { m_last = p; }
    109    void appendSlot(int i, int cid, int gid, int fid, size_t coffset);
    110    Slot *newSlot();
    111    void freeSlot(Slot *);
    112    SlotJustify *newJustify();
    113    void freeJustify(SlotJustify *aJustify);
    114    Position positionSlots(const Font *font=0, Slot *first=0, Slot *last=0, bool isRtl = false, bool isFinal = true);
    115    void associateChars(int offset, size_t num);
    116    void linkClusters(Slot *first, Slot *last);
    117    uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); }
    118    uint16 findClassIndex(uint16 cid, uint16 gid) const { return m_silf->findClassIndex(cid, gid); }
    119    int addFeatures(const Features& feats) { m_feats.push_back(feats); return int(m_feats.size()) - 1; }
    120    uint32 getFeature(int index, uint8 findex) const { const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex); if (!pFR) return 0; else return pFR->getFeatureVal(m_feats[index]); }
    121    void setFeature(int index, uint8 findex, uint32 val) {
    122        const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex);
    123        if (pFR)
    124        {
    125            if (val > pFR->maxVal()) val = pFR->maxVal();
    126            pFR->applyValToFeature(val, m_feats[index]);
    127        } }
    128    int8 dir() const { return m_dir; }
    129    void dir(int8 val) { m_dir = val; }
    130    bool currdir() const { return ((m_dir >> 6) ^ m_dir) & 1; }
    131    uint8 passBits() const { return m_passBits; }
    132    void mergePassBits(const uint8 val) { m_passBits &= val; }
    133    int16 glyphAttr(uint16 gid, uint16 gattr) const { const GlyphFace * p = m_face->glyphs().glyphSafe(gid); return p ? p->attrs()[gattr] : 0; }
    134    int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel, bool rtl) const;
    135    float glyphAdvance(uint16 gid) const { return m_face->glyphs().glyph(gid)->theAdvance().x; }
    136    const Rect &theGlyphBBoxTemporary(uint16 gid) const { return m_face->glyphs().glyph(gid)->theBBox(); }   //warning value may become invalid when another glyph is accessed
    137    Slot *findRoot(Slot *is) const { return is->attachedTo() ? findRoot(is->attachedTo()) : is; }
    138    int numAttrs() const { return m_silf->numUser(); }
    139    int defaultOriginal() const { return m_defaultOriginal; }
    140    const Face * getFace() const { return m_face; }
    141    const Features & getFeatures(unsigned int /*charIndex*/) { assert(m_feats.size() == 1); return m_feats[0]; }
    142    void bidiPass(int paradir, uint8 aMirror);
    143    int8 getSlotBidiClass(Slot *s) const;
    144    void doMirror(uint16 aMirror);
    145    Slot *addLineEnd(Slot *nSlot);
    146    void delLineEnd(Slot *s);
    147    bool hasJustification() const { return m_justifies.size() != 0; }
    148    void reverseSlots();
    149 
    150    bool isWhitespace(const int cid) const;
    151    bool hasCollisionInfo() const { return (m_flags & SEG_HASCOLLISIONS) && m_collisions; }
    152    SlotCollision *collisionInfo(const Slot *s) const { return m_collisions ? m_collisions + s->index() : 0; }
    153    CLASS_NEW_DELETE
    154 
    155 public:       //only used by: GrSegment* makeAndInitialize(const GrFont *font, const GrFace *face, uint32 script, const FeaturesHandle& pFeats/*must not be IsNull*/, encform enc, const void* pStart, size_t nChars, int dir);
    156    bool read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void*pStart, size_t nChars);
    157    void finalise(const Font *font, bool reverse=false);
    158    float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
    159    bool initCollisions();
    160 
    161 private:
    162    Position        m_advance;          // whole segment advance
    163    SlotRope        m_slots;            // Vector of slot buffers
    164    AttributeRope   m_userAttrs;        // Vector of userAttrs buffers
    165    JustifyRope     m_justifies;        // Slot justification info buffers
    166    FeatureList     m_feats;            // feature settings referenced by charinfos in this segment
    167    Slot          * m_freeSlots;        // linked list of free slots
    168    SlotJustify   * m_freeJustifies;    // Slot justification blocks free list
    169    CharInfo      * m_charinfo;         // character info, one per input character
    170    SlotCollision * m_collisions;
    171    const Face    * m_face;             // GrFace
    172    const Silf    * m_silf;
    173    Slot          * m_first;            // first slot in segment
    174    Slot          * m_last;             // last slot in segment
    175    size_t          m_bufSize,          // how big a buffer to create when need more slots
    176                    m_numGlyphs,
    177                    m_numCharinfo;      // size of the array and number of input characters
    178    int             m_defaultOriginal;  // number of whitespace chars in the string
    179    int8            m_dir;
    180    uint8           m_flags,            // General purpose flags
    181                    m_passBits;         // if bit set then skip pass
    182 };
    183 
    184 inline
    185 int8 Segment::getSlotBidiClass(Slot *s) const
    186 {
    187    int8 res = s->getBidiClass();
    188    if (res != -1) return res;
    189    res = int8(glyphAttr(s->gid(), m_silf->aBidi()));
    190    s->setBidiClass(res);
    191    return res;
    192 }
    193 
    194 inline
    195 void Segment::finalise(const Font *font, bool reverse)
    196 {
    197    if (!m_first || !m_last) return;
    198 
    199    m_advance = positionSlots(font, m_first, m_last, m_silf->dir(), true);
    200    //associateChars(0, m_numCharinfo);
    201    if (reverse && currdir() != (m_dir & 1))
    202        reverseSlots();
    203    linkClusters(m_first, m_last);
    204 }
    205 
    206 inline
    207 int32 Segment::getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel, bool rtl) const {
    208    if (attrLevel > 0)
    209    {
    210        Slot *is = findRoot(iSlot);
    211        return is->clusterMetric(this, metric, attrLevel, rtl);
    212    }
    213    else
    214        return m_face->getGlyphMetric(iSlot->gid(), metric);
    215 }
    216 
    217 inline
    218 bool Segment::isWhitespace(const int cid) const
    219 {
    220    return ((cid >= 0x0009) * (cid <= 0x000D)
    221         + (cid == 0x0020)
    222         + (cid == 0x0085)
    223         + (cid == 0x00A0)
    224         + (cid == 0x1680)
    225         + (cid == 0x180E)
    226         + (cid >= 0x2000) * (cid <= 0x200A)
    227         + (cid == 0x2028)
    228         + (cid == 0x2029)
    229         + (cid == 0x202F)
    230         + (cid == 0x205F)
    231         + (cid == 0x3000)) != 0;
    232 }
    233 
    234 } // namespace graphite2
    235 
    236 struct gr_segment : public graphite2::Segment {};