gfx/graphite2/src/GlyphFaceCache.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* GRAPHITE2 LICENSING
michael@0 2
michael@0 3 Copyright 2010, SIL International
michael@0 4 All rights reserved.
michael@0 5
michael@0 6 This library is free software; you can redistribute it and/or modify
michael@0 7 it under the terms of the GNU Lesser General Public License as published
michael@0 8 by the Free Software Foundation; either version 2.1 of License, or
michael@0 9 (at your option) any later version.
michael@0 10
michael@0 11 This program is distributed in the hope that it will be useful,
michael@0 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
michael@0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michael@0 14 Lesser General Public License for more details.
michael@0 15
michael@0 16 You should also have received a copy of the GNU Lesser General Public
michael@0 17 License along with this library in the file named "LICENSE".
michael@0 18 If not, write to the Free Software Foundation, 51 Franklin Street,
michael@0 19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
michael@0 20 internet at http://www.fsf.org/licenses/lgpl.html.
michael@0 21
michael@0 22 Alternatively, the contents of this file may be used under the terms of the
michael@0 23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
michael@0 24 License, as published by the Free Software Foundation, either version 2
michael@0 25 of the License or (at your option) any later version.
michael@0 26 */
michael@0 27 #include "inc/GlyphFaceCache.h"
michael@0 28 #include "graphite2/Font.h"
michael@0 29 #include "inc/Face.h" //for the tags
michael@0 30 #include "inc/Endian.h"
michael@0 31
michael@0 32 using namespace graphite2;
michael@0 33
michael@0 34 /*virtual*/ bool GlyphFaceCacheHeader::initialize(const Face & face, const bool dumb_font) //return result indicates success. Do not use if failed.
michael@0 35 {
michael@0 36 if ((m_pLoca = face.getTable(Tag::loca, &m_lLoca)) == NULL) return false;
michael@0 37 if ((m_pHead = face.getTable(Tag::head)) == NULL) return false;
michael@0 38 if ((m_pGlyf = face.getTable(Tag::glyf, &m_lGlyf)) == NULL) return false;
michael@0 39 if ((m_pHmtx = face.getTable(Tag::hmtx, &m_lHmtx)) == NULL) return false;
michael@0 40 if ((m_pHHea = face.getTable(Tag::hhea)) == NULL) return false;
michael@0 41
michael@0 42 const void* pMaxp = face.getTable(Tag::maxp);
michael@0 43 if (pMaxp == NULL) return false;
michael@0 44 m_nGlyphs = m_nGlyphsWithGraphics = (unsigned short)TtfUtil::GlyphCount(pMaxp);
michael@0 45 if (TtfUtil::LocaLookup(m_nGlyphs-1, m_pLoca, m_lLoca, m_pHead) == size_t(-1))
michael@0 46 return false; // This will fail if m_nGlyphs is wildly out of range.
michael@0 47
michael@0 48 if (!dumb_font)
michael@0 49 {
michael@0 50 if ((m_pGlat = face.getTable(Tag::Glat, &m_lGlat)) == NULL) return false;
michael@0 51 m_fGlat = be::peek<uint32>(m_pGlat);
michael@0 52 size_t lGloc;
michael@0 53 if ((m_pGloc = face.getTable(Tag::Gloc, &lGloc)) == NULL) return false;
michael@0 54 if (lGloc < 6) return false;
michael@0 55 int version = be::read<uint32>(m_pGloc);
michael@0 56 if (version != 0x00010000) return false;
michael@0 57
michael@0 58 const uint16 locFlags = be::read<uint16>(m_pGloc);
michael@0 59 m_numAttrs = be::read<uint16>(m_pGloc);
michael@0 60 if (m_numAttrs > 0x1000) return false; // is this hard limit appropriate?
michael@0 61
michael@0 62 if (locFlags & 1)
michael@0 63 {
michael@0 64 m_locFlagsUse32Bit = true;
michael@0 65 m_nGlyphsWithAttributes = (unsigned short)((lGloc - 12) / 4);
michael@0 66 }
michael@0 67 else
michael@0 68 {
michael@0 69 m_locFlagsUse32Bit = false;
michael@0 70 m_nGlyphsWithAttributes = (unsigned short)((lGloc - 10) / 2);
michael@0 71 }
michael@0 72
michael@0 73 if (m_nGlyphsWithAttributes > m_nGlyphs)
michael@0 74 m_nGlyphs = m_nGlyphsWithAttributes;
michael@0 75 }
michael@0 76
michael@0 77 return true;
michael@0 78 }
michael@0 79
michael@0 80 GlyphFaceCache* GlyphFaceCache::makeCache(const GlyphFaceCacheHeader& hdr)
michael@0 81 {
michael@0 82 return new (hdr) GlyphFaceCache(hdr);
michael@0 83 }
michael@0 84
michael@0 85 GlyphFaceCache::GlyphFaceCache(const GlyphFaceCacheHeader& hdr)
michael@0 86 : GlyphFaceCacheHeader(hdr)
michael@0 87 {
michael@0 88 unsigned int nGlyphs = numGlyphs();
michael@0 89
michael@0 90 for (unsigned int i = 0; i < nGlyphs; i++)
michael@0 91 {
michael@0 92 *glyphPtrDirect(i) = NULL;
michael@0 93 }
michael@0 94 }
michael@0 95
michael@0 96 GlyphFaceCache::~GlyphFaceCache()
michael@0 97 {
michael@0 98 unsigned int nGlyphs = numGlyphs();
michael@0 99 int deltaPointers = (*glyphPtrDirect(nGlyphs-1u) - *glyphPtrDirect(0u));
michael@0 100 if ((nGlyphs > 0u) && (deltaPointers == static_cast<int>(nGlyphs - 1)))
michael@0 101 {
michael@0 102 for (unsigned int i=0 ; i<nGlyphs; ++i)
michael@0 103 {
michael@0 104 GlyphFace *p = *glyphPtrDirect(i);
michael@0 105 assert (p);
michael@0 106 p->~GlyphFace();
michael@0 107 }
michael@0 108 free (*glyphPtrDirect(0));
michael@0 109 }
michael@0 110 else
michael@0 111 {
michael@0 112 for (unsigned int i=0 ; i<nGlyphs; ++i)
michael@0 113 {
michael@0 114 GlyphFace *p = *glyphPtrDirect(i);
michael@0 115 if (p)
michael@0 116 {
michael@0 117 p->~GlyphFace();
michael@0 118 free(p);
michael@0 119 }
michael@0 120 }
michael@0 121 }
michael@0 122 }
michael@0 123
michael@0 124 void GlyphFaceCache::loadAllGlyphs()
michael@0 125 {
michael@0 126 unsigned int nGlyphs = numGlyphs();
michael@0 127 // size_t sparse_size = 0;
michael@0 128 GlyphFace * glyphs = gralloc<GlyphFace>(nGlyphs);
michael@0 129 for (unsigned short glyphid = 0; glyphid < nGlyphs; glyphid++)
michael@0 130 {
michael@0 131 GlyphFace **p = glyphPtrDirect(glyphid);
michael@0 132 *p = &(glyphs[glyphid]);
michael@0 133 new(*p) GlyphFace(*this, glyphid);
michael@0 134 // sparse_size += (*p)->m_attrs._sizeof();
michael@0 135 }
michael@0 136 // const size_t flat_size = nGlyphs*(sizeof(uint16*) + sizeof(uint16)*numAttrs());
michael@0 137 // assert(sparse_size <= flat_size);
michael@0 138 }
michael@0 139
michael@0 140 /*virtual*/ const GlyphFace *GlyphFaceCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid
michael@0 141 {
michael@0 142 GlyphFace **p = glyphPtrDirect(glyphid);
michael@0 143 if (*p)
michael@0 144 return *p;
michael@0 145
michael@0 146 *p = (GlyphFace*)malloc(sizeof(GlyphFace));
michael@0 147 new(*p) GlyphFace(*this, glyphid);
michael@0 148 return *p;
michael@0 149 }

mercurial