LCOV - code coverage report
Current view: directory - gfx/graphite2/src - Slot.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 196 0 0.0 %
Date: 2012-06-02 Functions: 11 0 0.0 %

       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                 : #include "inc/Segment.h"
      28                 : #include "inc/Slot.h"
      29                 : #include "inc/CharInfo.h"
      30                 : #include "inc/Rule.h"
      31                 : 
      32                 : 
      33                 : using namespace graphite2;
      34                 : 
      35               0 : Slot::Slot() :
      36                 :     m_next(NULL), m_prev(NULL),
      37                 :     m_glyphid(0), m_realglyphid(0), m_original(0), m_before(0), m_after(0),
      38                 :     m_parent(NULL), m_child(NULL), m_sibling(NULL),
      39                 :     m_position(0, 0), m_shift(0, 0), m_advance(-1, -1),
      40                 :     m_attach(0, 0), m_with(0, 0), m_just(0.),
      41               0 :     m_flags(0), m_attLevel(0)
      42                 :     // Do not set m_userAttr since it is set *before* new is called since this
      43                 :     // is used as a positional new to reset the GrSlot
      44                 : {
      45               0 : }
      46                 : 
      47                 : // take care, this does not copy any of the GrSlot pointer fields
      48               0 : void Slot::set(const Slot & orig, int charOffset, uint8 numUserAttr)
      49                 : {
      50                 :     // leave m_next and m_prev unchanged
      51               0 :     m_glyphid = orig.m_glyphid;
      52               0 :     m_realglyphid = orig.m_realglyphid;
      53               0 :     m_original = orig.m_original + charOffset;
      54               0 :     m_before = orig.m_before + charOffset;
      55               0 :     m_after = orig.m_after + charOffset;
      56               0 :     m_parent = NULL;
      57               0 :     m_child = NULL;
      58               0 :     m_sibling = NULL;
      59               0 :     m_position = orig.m_position;
      60               0 :     m_shift = orig.m_shift;
      61               0 :     m_advance = orig.m_advance;
      62               0 :     m_attach = orig.m_attach;
      63               0 :     m_with = orig.m_with;
      64               0 :     m_flags = orig.m_flags;
      65               0 :     m_attLevel = orig.m_attLevel;
      66               0 :     assert(!orig.m_userAttr || m_userAttr);
      67               0 :     if (m_userAttr && orig.m_userAttr)
      68                 :     {
      69               0 :         memcpy(m_userAttr, orig.m_userAttr, numUserAttr * sizeof(*m_userAttr));
      70                 :     }
      71               0 : }
      72                 : 
      73               0 : void Slot::update(int /*numGrSlots*/, int numCharInfo, Position &relpos)
      74                 : {
      75               0 :     m_before += numCharInfo;
      76               0 :     m_after += numCharInfo;
      77               0 :     m_position = m_position + relpos;
      78               0 : }
      79                 : 
      80               0 : Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, float & cMin, uint8 attrLevel, float & clusterMin)
      81                 : {
      82               0 :     if (attrLevel && m_attLevel > attrLevel) return Position(0, 0);
      83               0 :     float scale = 1.0;
      84               0 :     Position shift = m_shift + Position(m_just, 0);
      85               0 :     float tAdvance = m_advance.x + m_just;
      86               0 :     const GlyphFace * glyphFace = seg->getFace()->getGlyphFaceCache()->glyphSafe(glyph());
      87               0 :     if (font)
      88                 :     {
      89               0 :         scale = font->scale();
      90               0 :         shift *= scale;
      91               0 :         if (font->isHinted())
      92                 :         {
      93               0 :             if (glyphFace)
      94               0 :                 tAdvance = (m_advance.x - glyphFace->theAdvance().x) * scale + font->advance(m_glyphid);
      95                 :             else
      96               0 :                 tAdvance = (m_advance.x - seg->glyphAdvance(glyph())) * scale + font->advance(m_glyphid);
      97                 :         }
      98                 :         else
      99               0 :             tAdvance *= scale;
     100                 :     }    
     101               0 :     Position res;
     102                 : 
     103               0 :     m_position = base + shift;
     104               0 :     if (!m_parent)
     105                 :     {
     106               0 :         res = base + Position(tAdvance, m_advance.y * scale);
     107               0 :         cMin = 0.;
     108               0 :         clusterMin = base.x;
     109                 :     }
     110                 :     else
     111                 :     {
     112                 :         float tAdv;
     113               0 :         m_position += (m_attach - m_with) * scale;
     114               0 :         tAdv = tAdvance > 0.f ? m_position.x + tAdvance - shift.x : 0.f;
     115               0 :         res = Position(tAdv, 0);
     116               0 :         if (m_position.x < clusterMin) clusterMin = m_position.x;
     117                 :     }
     118                 : 
     119               0 :     if (glyphFace)
     120                 :     {
     121               0 :         Rect ourBbox = glyphFace->theBBox() * scale + m_position;
     122               0 :         bbox = bbox.widen(ourBbox);
     123                 :     }
     124                 :     //Rect ourBbox = seg->theGlyphBBoxTemporary(glyph()) * scale + m_position;
     125                 :     //bbox->widen(ourBbox);
     126                 : 
     127               0 :     if (m_parent && m_position.x < cMin) cMin = m_position.x;
     128                 : 
     129               0 :     if (m_child && m_child != this && m_child->attachedTo() == this)
     130                 :     {
     131               0 :         Position tRes = m_child->finalise(seg, font, m_position, bbox, cMin, attrLevel, clusterMin);
     132               0 :         if (tRes.x > res.x) res = tRes;
     133                 :     }
     134                 : 
     135               0 :     if (m_parent && m_sibling && m_sibling != this && m_sibling->attachedTo() == m_parent)
     136                 :     {
     137               0 :         Position tRes = m_sibling->finalise(seg, font, base, bbox, cMin, attrLevel, clusterMin);
     138               0 :         if (tRes.x > res.x) res = tRes;
     139                 :     }
     140                 :     
     141               0 :     if (!m_parent)
     142                 :     {
     143               0 :         if (cMin < 0)
     144                 :         {
     145               0 :             Position adj = Position(-cMin, 0.);
     146               0 :             res += adj;
     147               0 :             m_position += adj;
     148               0 :             if (m_child) m_child->floodShift(adj);
     149                 :         }
     150               0 :         else if ((seg->dir() & 1) && (clusterMin < base.x))
     151                 :         {
     152               0 :             Position adj = Position(base.x - clusterMin, 0.);
     153               0 :             res += adj;
     154               0 :             m_position += adj;
     155               0 :             if (m_child) m_child->floodShift(adj);
     156                 :         }
     157                 :     }
     158               0 :     return res;
     159                 : }
     160                 : 
     161               0 : uint32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel)
     162                 : {
     163               0 :     Position base;
     164               0 :     Rect bbox = seg->theGlyphBBoxTemporary(gid());
     165               0 :     float cMin = 0.;
     166               0 :     float clusterMin = 0.;
     167               0 :     Position res = finalise(seg, NULL, base, bbox, cMin, attrLevel, clusterMin);
     168                 : 
     169               0 :     switch (metrics(metric))
     170                 :     {
     171                 :     case kgmetLsb :
     172               0 :         return static_cast<uint32>(bbox.bl.x);
     173                 :     case kgmetRsb :
     174               0 :         return static_cast<uint32>(res.x - bbox.tr.x);
     175                 :     case kgmetBbTop :
     176               0 :         return static_cast<uint32>(bbox.tr.y);
     177                 :     case kgmetBbBottom :
     178               0 :         return static_cast<uint32>(bbox.bl.y);
     179                 :     case kgmetBbLeft :
     180               0 :         return static_cast<uint32>(bbox.bl.x);
     181                 :     case kgmetBbRight :
     182               0 :         return static_cast<uint32>(bbox.tr.x);
     183                 :     case kgmetBbWidth :
     184               0 :         return static_cast<uint32>(bbox.tr.x - bbox.bl.x);
     185                 :     case kgmetBbHeight :
     186               0 :         return static_cast<uint32>(bbox.tr.y - bbox.bl.y);
     187                 :     case kgmetAdvWidth :
     188               0 :         return static_cast<uint32>(res.x);
     189                 :     case kgmetAdvHeight :
     190               0 :         return static_cast<uint32>(res.y);
     191                 :     default :
     192               0 :         return 0;
     193                 :     }
     194                 : }
     195                 : 
     196               0 : int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
     197                 : {
     198               0 :     if (!this) return 0;
     199               0 :     if (ind == gr_slatUserDefnV1)
     200                 :     {
     201               0 :         ind = gr_slatUserDefn;
     202               0 :         subindex = 0;
     203                 :     }
     204               0 :     switch (ind)
     205                 :     {
     206               0 :     case gr_slatAdvX :          return int(m_advance.x);
     207               0 :     case gr_slatAdvY :          return int(m_advance.y);
     208               0 :     case gr_slatAttTo :         return 0;
     209               0 :     case gr_slatAttX :          return int(m_attach.x);
     210               0 :     case gr_slatAttY :          return int(m_attach.y);
     211                 :     case gr_slatAttXOff :
     212               0 :     case gr_slatAttYOff :       return 0;
     213               0 :     case gr_slatAttWithX :  return int(m_with.x);
     214               0 :     case gr_slatAttWithY :  return int(m_with.y);
     215                 :     case gr_slatAttWithXOff:
     216               0 :     case gr_slatAttWithYOff:return 0;
     217               0 :     case gr_slatAttLevel :      return m_attLevel;
     218               0 :     case gr_slatBreak :         return seg->charinfo(m_original)->breakWeight();
     219               0 :     case gr_slatCompRef :       return 0;
     220               0 :     case gr_slatDir :           return seg->dir();
     221               0 :     case gr_slatInsert :        return isInsertBefore();
     222               0 :     case gr_slatPosX :          return int(m_position.x); // but need to calculate it
     223               0 :     case gr_slatPosY :          return int(m_position.y);
     224               0 :     case gr_slatShiftX :        return int(m_shift.x);
     225               0 :     case gr_slatShiftY :        return int(m_shift.y);
     226               0 :     case gr_slatMeasureSol:     return -1; // err what's this?
     227               0 :     case gr_slatMeasureEol: return -1;
     228                 :     case gr_slatJStretch :
     229                 :     case gr_slatJShrink :
     230                 :     case gr_slatJStep :
     231               0 :     case gr_slatJWeight :       return 0;
     232               0 :     case gr_slatJWidth :        return m_just;
     233               0 :     case gr_slatUserDefn :      return m_userAttr[subindex];
     234               0 :     default :                           return 0;
     235                 :     }
     236                 : }
     237                 : 
     238               0 : void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, const SlotMap & map)
     239                 : {
     240               0 :     if (!this) return;
     241               0 :     if (ind == gr_slatUserDefnV1)
     242                 :     {
     243               0 :         ind = gr_slatUserDefn;
     244               0 :         subindex = 0;
     245                 :     }
     246               0 :     switch (ind)
     247                 :     {
     248               0 :     case gr_slatAdvX :  m_advance.x = value; break;
     249               0 :     case gr_slatAdvY :  m_advance.y = value; break;
     250                 :     case gr_slatAttTo :
     251                 :     {
     252               0 :         const uint16 idx = uint16(value);
     253               0 :         if (idx < map.size() && map[idx])
     254                 :         {
     255               0 :             Slot *other = map[idx];
     256               0 :             if (other != this && other->child(this))
     257                 :             {
     258               0 :                 attachTo(other);
     259               0 :                 m_attach = Position(seg->glyphAdvance(other->gid()), 0);
     260                 :             }
     261                 :         }
     262               0 :         break;
     263                 :     }
     264               0 :     case gr_slatAttX :                  m_attach.x = value; break;
     265               0 :     case gr_slatAttY :                  m_attach.y = value; break;
     266                 :     case gr_slatAttXOff :
     267               0 :     case gr_slatAttYOff :               break;
     268               0 :     case gr_slatAttWithX :              m_with.x = value; break;
     269               0 :     case gr_slatAttWithY :              m_with.y = value; break;
     270                 :     case gr_slatAttWithXOff :
     271               0 :     case gr_slatAttWithYOff :   break;
     272                 :     case gr_slatAttLevel :
     273               0 :         m_attLevel = byte(value);
     274               0 :         break;
     275                 :     case gr_slatBreak :
     276               0 :         seg->charinfo(m_original)->breakWeight(value);
     277               0 :         break;
     278               0 :     case gr_slatCompRef :       break;      // not sure what to do here
     279               0 :     case gr_slatDir :           break;  // read only
     280                 :     case gr_slatInsert :
     281               0 :         markInsertBefore(value? true : false);
     282               0 :         break;
     283               0 :     case gr_slatPosX :          break; // can't set these here
     284               0 :     case gr_slatPosY :          break;
     285               0 :     case gr_slatShiftX :        m_shift.x = value; break;
     286               0 :     case gr_slatShiftY :    m_shift.y = value; break;
     287               0 :     case gr_slatMeasureSol :    break;
     288               0 :     case gr_slatMeasureEol :    break;
     289               0 :     case gr_slatJStretch :      break;  // handle these later
     290               0 :     case gr_slatJShrink :       break;
     291               0 :     case gr_slatJStep :         break;
     292               0 :     case gr_slatJWeight :       break;
     293               0 :     case gr_slatJWidth :        m_just = value; break;
     294               0 :     case gr_slatUserDefn :  m_userAttr[subindex] = value; break;
     295                 :     default :
     296               0 :         break;
     297                 :     }
     298                 : }
     299                 : 
     300               0 : bool Slot::child(Slot *ap)
     301                 : {
     302               0 :     if (this == ap) return false;
     303               0 :     else if (ap == m_child) return true;
     304               0 :     else if (!m_child)
     305               0 :         m_child = ap;
     306                 :     else
     307               0 :         return m_child->sibling(ap);
     308               0 :     return true;
     309                 : }
     310                 : 
     311               0 : bool Slot::sibling(Slot *ap)
     312                 : {
     313               0 :     if (this == ap) return false;
     314               0 :     else if (ap == m_sibling) return true;
     315               0 :     else if (!m_sibling || !ap)
     316               0 :         m_sibling = ap;
     317                 :     else
     318               0 :         return m_sibling->sibling(ap);
     319               0 :     return true;
     320                 : }
     321                 : 
     322               0 : void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
     323                 : {
     324               0 :     m_glyphid = glyphid;
     325               0 :     if (!theGlyph)
     326                 :     {
     327               0 :         theGlyph = seg->getFace()->getGlyphFaceCache()->glyphSafe(glyphid);
     328               0 :         if (!theGlyph)
     329                 :         {
     330               0 :             m_realglyphid = 0;
     331               0 :             m_advance = Position(0.,0.);
     332               0 :             return;
     333                 :         }
     334                 :     }
     335               0 :     m_realglyphid = theGlyph->getAttr(seg->silf()->aPseudo());
     336               0 :     if (m_realglyphid)
     337                 :     {
     338               0 :         const GlyphFace *aGlyph = seg->getFace()->getGlyphFaceCache()->glyphSafe(m_realglyphid);
     339               0 :         if (aGlyph) theGlyph = aGlyph;
     340                 :     }
     341               0 :     m_advance = Position(theGlyph->theAdvance().x, 0.);
     342                 : }
     343                 : 
     344               0 : void Slot::floodShift(Position adj)
     345                 : {
     346               0 :     m_position += adj;
     347               0 :     if (m_child) m_child->floodShift(adj);
     348               0 :     if (m_sibling) m_sibling->floodShift(adj);
     349               0 : }

Generated by: LCOV version 1.7