gfx/graphite2/src/inc/Segment.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/graphite2/src/inc/Segment.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,273 @@
     1.4 +/*  GRAPHITE2 LICENSING
     1.5 +
     1.6 +    Copyright 2010, SIL International
     1.7 +    All rights reserved.
     1.8 +
     1.9 +    This library is free software; you can redistribute it and/or modify
    1.10 +    it under the terms of the GNU Lesser General Public License as published
    1.11 +    by the Free Software Foundation; either version 2.1 of License, or
    1.12 +    (at your option) any later version.
    1.13 +
    1.14 +    This program is distributed in the hope that it will be useful,
    1.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.17 +    Lesser General Public License for more details.
    1.18 +
    1.19 +    You should also have received a copy of the GNU Lesser General Public
    1.20 +    License along with this library in the file named "LICENSE".
    1.21 +    If not, write to the Free Software Foundation, 51 Franklin Street, 
    1.22 +    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
    1.23 +    internet at http://www.fsf.org/licenses/lgpl.html.
    1.24 +
    1.25 +Alternatively, the contents of this file may be used under the terms of the
    1.26 +Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
    1.27 +License, as published by the Free Software Foundation, either version 2
    1.28 +of the License or (at your option) any later version.
    1.29 +*/
    1.30 +#pragma once
    1.31 +
    1.32 +#include "inc/Main.h"
    1.33 +
    1.34 +#include <cassert>
    1.35 +
    1.36 +#include "inc/CharInfo.h"
    1.37 +#include "inc/Face.h"
    1.38 +#include "inc/FeatureVal.h"
    1.39 +#include "inc/GlyphCache.h"
    1.40 +#include "inc/GlyphFace.h"
    1.41 +//#include "inc/Silf.h"
    1.42 +#include "inc/Slot.h"
    1.43 +#include "inc/Position.h"
    1.44 +#include "inc/List.h"
    1.45 +#include "inc/Bidi.h"
    1.46 +
    1.47 +#define MAX_SEG_GROWTH_FACTOR  256
    1.48 +
    1.49 +namespace graphite2 {
    1.50 +
    1.51 +typedef Vector<Features>        FeatureList;
    1.52 +typedef Vector<Slot *>          SlotRope;
    1.53 +typedef Vector<int16 *>        AttributeRope;
    1.54 +typedef Vector<SlotJustify *>   JustifyRope;
    1.55 +
    1.56 +#ifndef GRAPHITE2_NSEGCACHE
    1.57 +class SegmentScopeState;
    1.58 +#endif
    1.59 +class Font;
    1.60 +class Segment;
    1.61 +class Silf;
    1.62 +
    1.63 +enum SpliceParam {
    1.64 +/** sub-Segments longer than this are not cached
    1.65 + * (in Unicode code points) */
    1.66 +    eMaxSpliceSize = 96
    1.67 +};
    1.68 +
    1.69 +enum justFlags {
    1.70 +    gr_justStartInline = 1,
    1.71 +    gr_justEndInline = 2
    1.72 +};
    1.73 +
    1.74 +class SegmentScopeState
    1.75 +{
    1.76 +private:
    1.77 +    friend class Segment;
    1.78 +    Slot * realFirstSlot;
    1.79 +    Slot * slotBeforeScope;
    1.80 +    Slot * slotAfterScope;
    1.81 +    Slot * realLastSlot;
    1.82 +    size_t numGlyphsOutsideScope;
    1.83 +};
    1.84 +
    1.85 +class Segment
    1.86 +{
    1.87 +    // Prevent copying of any kind.
    1.88 +    Segment(const Segment&);
    1.89 +    Segment& operator=(const Segment&);
    1.90 +
    1.91 +public:
    1.92 +    unsigned int slotCount() const { return m_numGlyphs; }      //one slot per glyph
    1.93 +    void extendLength(int num) { m_numGlyphs += num; }
    1.94 +    Position advance() const { return m_advance; }
    1.95 +    bool runGraphite() { if (m_silf) return m_face->runGraphite(this, m_silf); else return true;};
    1.96 +    void chooseSilf(uint32 script) { m_silf = m_face->chooseSilf(script); }
    1.97 +    const Silf *silf() const { return m_silf; }
    1.98 +    unsigned int charInfoCount() const { return m_numCharinfo; }
    1.99 +    const CharInfo *charinfo(unsigned int index) const { return index < m_numCharinfo ? m_charinfo + index : NULL; }
   1.100 +    CharInfo *charinfo(unsigned int index) { return index < m_numCharinfo ? m_charinfo + index : NULL; }
   1.101 +    int8 dir() const { return m_dir; }
   1.102 +
   1.103 +    Segment(unsigned int numchars, const Face* face, uint32 script, int dir);
   1.104 +    ~Segment();
   1.105 +#ifndef GRAPHITE2_NSEGCACHE
   1.106 +    SegmentScopeState setScope(Slot * firstSlot, Slot * lastSlot, size_t subLength);
   1.107 +    void removeScope(SegmentScopeState & state);
   1.108 +    void append(const Segment &other);
   1.109 +    void splice(size_t offset, size_t length, Slot * const startSlot,
   1.110 +            Slot * endSlot, const Slot * srcSlot,
   1.111 +            const size_t numGlyphs);
   1.112 +#endif
   1.113 +    Slot *first() { return m_first; }
   1.114 +    void first(Slot *p) { m_first = p; }
   1.115 +    Slot *last() { return m_last; }
   1.116 +    void last(Slot *p) { m_last = p; }
   1.117 +    void appendSlot(int i, int cid, int gid, int fid, size_t coffset);
   1.118 +    Slot *newSlot();
   1.119 +    void freeSlot(Slot *);
   1.120 +    SlotJustify *newJustify();
   1.121 +    void freeJustify(SlotJustify *aJustify);
   1.122 +    Position positionSlots(const Font *font, Slot *first=0, Slot *last=0);
   1.123 +    void associateChars(int offset, int num);
   1.124 +    void linkClusters(Slot *first, Slot *last);
   1.125 +    uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); }
   1.126 +    uint16 findClassIndex(uint16 cid, uint16 gid) const { return m_silf->findClassIndex(cid, gid); }
   1.127 +    int addFeatures(const Features& feats) { m_feats.push_back(feats); return m_feats.size() - 1; }
   1.128 +    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]); }
   1.129 +    void dir(int8 val) { m_dir = val; }
   1.130 +    unsigned int passBits() const { return m_passBits; }
   1.131 +    void mergePassBits(const unsigned int val) { m_passBits &= val; }
   1.132 +    int16 glyphAttr(uint16 gid, uint16 gattr) const { const GlyphFace * p = m_face->glyphs().glyphSafe(gid); return p ? p->attrs()[gattr] : 0; }
   1.133 +    int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const;
   1.134 +    float glyphAdvance(uint16 gid) const { return m_face->glyphs().glyph(gid)->theAdvance().x; }
   1.135 +    const Rect &theGlyphBBoxTemporary(uint16 gid) const { return m_face->glyphs().glyph(gid)->theBBox(); }   //warning value may become invalid when another glyph is accessed
   1.136 +    Slot *findRoot(Slot *is) const { return is->attachedTo() ? findRoot(is->attachedTo()) : is; }
   1.137 +    int numAttrs() const { return m_silf->numUser(); }
   1.138 +    int defaultOriginal() const { return m_defaultOriginal; }
   1.139 +    const Face * getFace() const { return m_face; }
   1.140 +    const Features & getFeatures(unsigned int /*charIndex*/) { assert(m_feats.size() == 1); return m_feats[0]; }
   1.141 +    void bidiPass(uint8 aBidi, int paradir, uint8 aMirror);
   1.142 +    Slot *addLineEnd(Slot *nSlot);
   1.143 +    void delLineEnd(Slot *s);
   1.144 +    bool hasJustification() const { return m_justifies.size() != 0; }
   1.145 +
   1.146 +    bool isWhitespace(const int cid) const;
   1.147 +
   1.148 +    CLASS_NEW_DELETE
   1.149 +
   1.150 +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);
   1.151 +    bool read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void*pStart, size_t nChars);
   1.152 +    void prepare_pos(const Font *font);
   1.153 +    void finalise(const Font *font);
   1.154 +    float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
   1.155 +  
   1.156 +private:
   1.157 +    Position        m_advance;          // whole segment advance
   1.158 +    SlotRope        m_slots;            // Vector of slot buffers
   1.159 +    AttributeRope   m_userAttrs;        // Vector of userAttrs buffers
   1.160 +    JustifyRope     m_justifies;        // Slot justification info buffers
   1.161 +    FeatureList     m_feats;            // feature settings referenced by charinfos in this segment
   1.162 +    Slot          * m_freeSlots;        // linked list of free slots
   1.163 +    SlotJustify   * m_freeJustifies;    // Slot justification blocks free list
   1.164 +    CharInfo      * m_charinfo;         // character info, one per input character
   1.165 +    const Face    * m_face;             // GrFace
   1.166 +    const Silf    * m_silf;
   1.167 +    Slot          * m_first;            // first slot in segment
   1.168 +    Slot          * m_last;             // last slot in segment
   1.169 +    unsigned int    m_bufSize,          // how big a buffer to create when need more slots
   1.170 +                    m_numGlyphs,
   1.171 +                    m_numCharinfo,      // size of the array and number of input characters
   1.172 +                    m_passBits;         // if bit set then skip pass
   1.173 +    int             m_defaultOriginal;  // number of whitespace chars in the string
   1.174 +    int8            m_dir;
   1.175 +};
   1.176 +
   1.177 +
   1.178 +
   1.179 +inline
   1.180 +void Segment::finalise(const Font *font)
   1.181 +{
   1.182 +    if (!m_first) return;
   1.183 +
   1.184 +    m_advance = positionSlots(font);
   1.185 +    associateChars(0, m_numCharinfo);
   1.186 +    linkClusters(m_first, m_last);
   1.187 +}
   1.188 +
   1.189 +inline
   1.190 +int32 Segment::getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const {
   1.191 +    if (attrLevel > 0)
   1.192 +    {
   1.193 +        Slot *is = findRoot(iSlot);
   1.194 +        return is->clusterMetric(this, metric, attrLevel);
   1.195 +    }
   1.196 +    else
   1.197 +        return m_face->getGlyphMetric(iSlot->gid(), metric);
   1.198 +}
   1.199 +
   1.200 +inline
   1.201 +bool Segment::isWhitespace(const int cid) const
   1.202 +{
   1.203 +    return ((cid >= 0x0009) * (cid <= 0x000D)
   1.204 +         + (cid == 0x0020)
   1.205 +         + (cid == 0x0085)
   1.206 +         + (cid == 0x00A0)
   1.207 +         + (cid == 0x1680)
   1.208 +         + (cid == 0x180E)
   1.209 +         + (cid >= 0x2000) * (cid <= 0x200A)
   1.210 +         + (cid == 0x2028)
   1.211 +         + (cid == 0x2029)
   1.212 +         + (cid == 0x202F)
   1.213 +         + (cid == 0x205F)
   1.214 +         + (cid == 0x3000)) != 0;
   1.215 +}
   1.216 +
   1.217 +//inline
   1.218 +//bool Segment::isWhitespace(const int cid) const
   1.219 +//{
   1.220 +//    switch (cid >> 8)
   1.221 +//    {
   1.222 +//        case 0x00:
   1.223 +//            switch (cid)
   1.224 +//            {
   1.225 +//            case 0x09:
   1.226 +//            case 0x0A:
   1.227 +//            case 0x0B:
   1.228 +//            case 0x0C:
   1.229 +//            case 0x0D:
   1.230 +//            case 0x20:
   1.231 +//                return true;
   1.232 +//            default:
   1.233 +//                break;
   1.234 +//            }
   1.235 +//            break;
   1.236 +//        case 0x16:
   1.237 +//            return cid == 0x1680;
   1.238 +//            break;
   1.239 +//        case 0x18:
   1.240 +//            return cid == 0x180E;
   1.241 +//            break;
   1.242 +//        case 0x20:
   1.243 +//            switch (cid)
   1.244 +//            {
   1.245 +//            case 0x00:
   1.246 +//            case 0x01:
   1.247 +//            case 0x02:
   1.248 +//            case 0x03:
   1.249 +//            case 0x04:
   1.250 +//            case 0x05:
   1.251 +//            case 0x06:
   1.252 +//            case 0x07:
   1.253 +//            case 0x08:
   1.254 +//            case 0x09:
   1.255 +//            case 0x0A:
   1.256 +//            case 0x28:
   1.257 +//            case 0x29:
   1.258 +//            case 0x2F:
   1.259 +//            case 0x5F:
   1.260 +//                return true
   1.261 +//            default:
   1.262 +//                break;
   1.263 +//            }
   1.264 +//            break;
   1.265 +//        case 0x30:
   1.266 +//            return cid == 0x3000;
   1.267 +//            break;
   1.268 +//    }
   1.269 +//
   1.270 +//    return false;
   1.271 +//}
   1.272 +
   1.273 +} // namespace graphite2
   1.274 +
   1.275 +struct gr_segment : public graphite2::Segment {};
   1.276 +

mercurial