gfx/graphite2/src/GlyphFaceCache.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/graphite2/src/GlyphFaceCache.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,149 @@
     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 +#include "inc/GlyphFaceCache.h"
    1.31 +#include "graphite2/Font.h"
    1.32 +#include "inc/Face.h"     //for the tags
    1.33 +#include "inc/Endian.h"
    1.34 +
    1.35 +using namespace graphite2;
    1.36 +
    1.37 +/*virtual*/ bool GlyphFaceCacheHeader::initialize(const Face & face, const bool dumb_font)    //return result indicates success. Do not use if failed.
    1.38 +{
    1.39 +    if ((m_pLoca = face.getTable(Tag::loca, &m_lLoca)) == NULL) return false;
    1.40 +    if ((m_pHead = face.getTable(Tag::head)) == NULL) return false;
    1.41 +    if ((m_pGlyf = face.getTable(Tag::glyf, &m_lGlyf)) == NULL) return false;
    1.42 +    if ((m_pHmtx = face.getTable(Tag::hmtx, &m_lHmtx)) == NULL) return false;
    1.43 +    if ((m_pHHea = face.getTable(Tag::hhea)) == NULL) return false;
    1.44 +
    1.45 +    const void* pMaxp = face.getTable(Tag::maxp);
    1.46 +    if (pMaxp == NULL) return false;
    1.47 +    m_nGlyphs = m_nGlyphsWithGraphics = (unsigned short)TtfUtil::GlyphCount(pMaxp);
    1.48 +    if (TtfUtil::LocaLookup(m_nGlyphs-1, m_pLoca, m_lLoca, m_pHead) == size_t(-1))
    1.49 +    	return false; // This will fail if m_nGlyphs is wildly out of range.
    1.50 +
    1.51 +    if (!dumb_font)
    1.52 +    {
    1.53 +		if ((m_pGlat = face.getTable(Tag::Glat, &m_lGlat)) == NULL) return false;
    1.54 +		m_fGlat = be::peek<uint32>(m_pGlat);
    1.55 +		size_t lGloc;
    1.56 +		if ((m_pGloc = face.getTable(Tag::Gloc, &lGloc)) == NULL) return false;
    1.57 +		if (lGloc < 6) return false;
    1.58 +		int version = be::read<uint32>(m_pGloc);
    1.59 +		if (version != 0x00010000) return false;
    1.60 +
    1.61 +		const uint16 locFlags = be::read<uint16>(m_pGloc);
    1.62 +		m_numAttrs = be::read<uint16>(m_pGloc);
    1.63 +		if (m_numAttrs > 0x1000) return false;                  // is this hard limit appropriate?
    1.64 +
    1.65 +		if (locFlags & 1)
    1.66 +		{
    1.67 +			m_locFlagsUse32Bit = true;
    1.68 +			m_nGlyphsWithAttributes = (unsigned short)((lGloc - 12) / 4);
    1.69 +		}
    1.70 +		else
    1.71 +		{
    1.72 +			m_locFlagsUse32Bit = false;
    1.73 +			m_nGlyphsWithAttributes = (unsigned short)((lGloc - 10) / 2);
    1.74 +		}
    1.75 +
    1.76 +		if (m_nGlyphsWithAttributes > m_nGlyphs)
    1.77 +	        m_nGlyphs = m_nGlyphsWithAttributes;
    1.78 +    }
    1.79 +
    1.80 +    return true;
    1.81 +}
    1.82 +
    1.83 +GlyphFaceCache* GlyphFaceCache::makeCache(const GlyphFaceCacheHeader& hdr)
    1.84 +{
    1.85 +    return new (hdr) GlyphFaceCache(hdr);
    1.86 +}
    1.87 +
    1.88 +GlyphFaceCache::GlyphFaceCache(const GlyphFaceCacheHeader& hdr)
    1.89 +:   GlyphFaceCacheHeader(hdr)
    1.90 +{
    1.91 +    unsigned int nGlyphs = numGlyphs();
    1.92 +    
    1.93 +    for (unsigned int i = 0; i < nGlyphs; i++)
    1.94 +    {
    1.95 +         *glyphPtrDirect(i) = NULL;
    1.96 +    }
    1.97 +}
    1.98 +
    1.99 +GlyphFaceCache::~GlyphFaceCache()
   1.100 +{
   1.101 +    unsigned int nGlyphs = numGlyphs();
   1.102 +    int deltaPointers = (*glyphPtrDirect(nGlyphs-1u) - *glyphPtrDirect(0u));
   1.103 +    if ((nGlyphs > 0u) && (deltaPointers == static_cast<int>(nGlyphs - 1)))
   1.104 +    {
   1.105 +        for (unsigned int i=0 ; i<nGlyphs; ++i)
   1.106 +        {
   1.107 +            GlyphFace *p = *glyphPtrDirect(i);
   1.108 +            assert (p);
   1.109 +            p->~GlyphFace();
   1.110 +        }
   1.111 +        free (*glyphPtrDirect(0));
   1.112 +    }
   1.113 +    else
   1.114 +    {
   1.115 +        for (unsigned int i=0 ; i<nGlyphs; ++i)
   1.116 +        {
   1.117 +            GlyphFace *p = *glyphPtrDirect(i);
   1.118 +            if (p)
   1.119 +            {
   1.120 +                p->~GlyphFace();
   1.121 +                free(p);
   1.122 +            }
   1.123 +        }
   1.124 +    }
   1.125 +}
   1.126 +
   1.127 +void GlyphFaceCache::loadAllGlyphs()
   1.128 +{
   1.129 +    unsigned int nGlyphs = numGlyphs();
   1.130 +//    size_t sparse_size = 0;
   1.131 +    GlyphFace * glyphs = gralloc<GlyphFace>(nGlyphs);
   1.132 +    for (unsigned short glyphid = 0; glyphid < nGlyphs; glyphid++)
   1.133 +    {
   1.134 +        GlyphFace **p = glyphPtrDirect(glyphid);
   1.135 +        *p = &(glyphs[glyphid]);
   1.136 +        new(*p) GlyphFace(*this, glyphid);
   1.137 +//        sparse_size += (*p)->m_attrs._sizeof();
   1.138 +    }
   1.139 +//    const size_t flat_size = nGlyphs*(sizeof(uint16*) + sizeof(uint16)*numAttrs());
   1.140 +//    assert(sparse_size <= flat_size);
   1.141 +}
   1.142 +
   1.143 +/*virtual*/ const GlyphFace *GlyphFaceCache::glyph(unsigned short glyphid) const      //result may be changed by subsequent call with a different glyphid
   1.144 +{ 
   1.145 +    GlyphFace **p = glyphPtrDirect(glyphid);
   1.146 +    if (*p)
   1.147 +        return *p;
   1.148 +
   1.149 +    *p = (GlyphFace*)malloc(sizeof(GlyphFace));
   1.150 +    new(*p) GlyphFace(*this, glyphid);
   1.151 +    return *p;
   1.152 +}

mercurial