gfx/thebes/gfxFontUtils.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/thebes/gfxFontUtils.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,955 @@
     1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef GFX_FONT_UTILS_H
    1.10 +#define GFX_FONT_UTILS_H
    1.11 +
    1.12 +#include "gfxPlatform.h"
    1.13 +#include "nsComponentManagerUtils.h"
    1.14 +#include "nsTArray.h"
    1.15 +#include "nsAutoPtr.h"
    1.16 +#include "mozilla/Likely.h"
    1.17 +#include "mozilla/Endian.h"
    1.18 +#include "mozilla/MemoryReporting.h"
    1.19 +
    1.20 +#include "zlib.h"
    1.21 +#include <algorithm>
    1.22 +
    1.23 +/* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
    1.24 +#ifdef __MINGW32__
    1.25 +#undef min
    1.26 +#undef max
    1.27 +#endif
    1.28 +
    1.29 +typedef struct hb_blob_t hb_blob_t;
    1.30 +
    1.31 +class gfxSparseBitSet {
    1.32 +private:
    1.33 +    enum { BLOCK_SIZE = 32 };   // ==> 256 codepoints per block
    1.34 +    enum { BLOCK_SIZE_BITS = BLOCK_SIZE * 8 };
    1.35 +    enum { BLOCK_INDEX_SHIFT = 8 };
    1.36 +
    1.37 +    struct Block {
    1.38 +        Block(const Block& aBlock) { memcpy(mBits, aBlock.mBits, sizeof(mBits)); }
    1.39 +        Block(unsigned char memsetValue = 0) { memset(mBits, memsetValue, BLOCK_SIZE); }
    1.40 +        uint8_t mBits[BLOCK_SIZE];
    1.41 +    };
    1.42 +
    1.43 +public:
    1.44 +    gfxSparseBitSet() { }
    1.45 +    gfxSparseBitSet(const gfxSparseBitSet& aBitset) {
    1.46 +        uint32_t len = aBitset.mBlocks.Length();
    1.47 +        mBlocks.AppendElements(len);
    1.48 +        for (uint32_t i = 0; i < len; ++i) {
    1.49 +            Block *block = aBitset.mBlocks[i];
    1.50 +            if (block)
    1.51 +                mBlocks[i] = new Block(*block);
    1.52 +        }
    1.53 +    }
    1.54 +
    1.55 +    bool Equals(const gfxSparseBitSet *aOther) const {
    1.56 +        if (mBlocks.Length() != aOther->mBlocks.Length()) {
    1.57 +            return false;
    1.58 +        }
    1.59 +        size_t n = mBlocks.Length();
    1.60 +        for (size_t i = 0; i < n; ++i) {
    1.61 +            const Block *b1 = mBlocks[i];
    1.62 +            const Block *b2 = aOther->mBlocks[i];
    1.63 +            if (!b1 != !b2) {
    1.64 +                return false;
    1.65 +            }
    1.66 +            if (!b1) {
    1.67 +                continue;
    1.68 +            }
    1.69 +            if (memcmp(&b1->mBits, &b2->mBits, BLOCK_SIZE) != 0) {
    1.70 +                return false;
    1.71 +            }
    1.72 +        }
    1.73 +        return true;
    1.74 +    }
    1.75 +
    1.76 +    bool test(uint32_t aIndex) const {
    1.77 +        NS_ASSERTION(mBlocks.DebugGetHeader(), "mHdr is null, this is bad");
    1.78 +        uint32_t blockIndex = aIndex/BLOCK_SIZE_BITS;
    1.79 +        if (blockIndex >= mBlocks.Length())
    1.80 +            return false;
    1.81 +        Block *block = mBlocks[blockIndex];
    1.82 +        if (!block)
    1.83 +            return false;
    1.84 +        return ((block->mBits[(aIndex>>3) & (BLOCK_SIZE - 1)]) & (1 << (aIndex & 0x7))) != 0;
    1.85 +    }
    1.86 +
    1.87 +#if PR_LOGGING
    1.88 +    // dump out contents of bitmap
    1.89 +    void Dump(const char* aPrefix, eGfxLog aWhichLog) const;
    1.90 +#endif
    1.91 +
    1.92 +    bool TestRange(uint32_t aStart, uint32_t aEnd) {
    1.93 +        uint32_t startBlock, endBlock, blockLen;
    1.94 +        
    1.95 +        // start point is beyond the end of the block array? return false immediately
    1.96 +        startBlock = aStart >> BLOCK_INDEX_SHIFT;
    1.97 +        blockLen = mBlocks.Length();
    1.98 +        if (startBlock >= blockLen) return false;
    1.99 +        
   1.100 +        // check for blocks in range, if none, return false
   1.101 +        uint32_t blockIndex;
   1.102 +        bool hasBlocksInRange = false;
   1.103 +
   1.104 +        endBlock = aEnd >> BLOCK_INDEX_SHIFT;
   1.105 +        blockIndex = startBlock;
   1.106 +        for (blockIndex = startBlock; blockIndex <= endBlock; blockIndex++) {
   1.107 +            if (blockIndex < blockLen && mBlocks[blockIndex])
   1.108 +                hasBlocksInRange = true;
   1.109 +        }
   1.110 +        if (!hasBlocksInRange) return false;
   1.111 +
   1.112 +        Block *block;
   1.113 +        uint32_t i, start, end;
   1.114 +        
   1.115 +        // first block, check bits
   1.116 +        if ((block = mBlocks[startBlock])) {
   1.117 +            start = aStart;
   1.118 +            end = std::min(aEnd, ((startBlock+1) << BLOCK_INDEX_SHIFT) - 1);
   1.119 +            for (i = start; i <= end; i++) {
   1.120 +                if ((block->mBits[(i>>3) & (BLOCK_SIZE - 1)]) & (1 << (i & 0x7)))
   1.121 +                    return true;
   1.122 +            }
   1.123 +        }
   1.124 +        if (endBlock == startBlock) return false;
   1.125 +
   1.126 +        // [2..n-1] blocks check bytes
   1.127 +        for (blockIndex = startBlock + 1; blockIndex < endBlock; blockIndex++) {
   1.128 +            uint32_t index;
   1.129 +            
   1.130 +            if (blockIndex >= blockLen || !(block = mBlocks[blockIndex])) continue;
   1.131 +            for (index = 0; index < BLOCK_SIZE; index++) {
   1.132 +                if (block->mBits[index]) 
   1.133 +                    return true;
   1.134 +            }
   1.135 +        }
   1.136 +        
   1.137 +        // last block, check bits
   1.138 +        if (endBlock < blockLen && (block = mBlocks[endBlock])) {
   1.139 +            start = endBlock << BLOCK_INDEX_SHIFT;
   1.140 +            end = aEnd;
   1.141 +            for (i = start; i <= end; i++) {
   1.142 +                if ((block->mBits[(i>>3) & (BLOCK_SIZE - 1)]) & (1 << (i & 0x7)))
   1.143 +                    return true;
   1.144 +            }
   1.145 +        }
   1.146 +        
   1.147 +        return false;
   1.148 +    }
   1.149 +    
   1.150 +    void set(uint32_t aIndex) {
   1.151 +        uint32_t blockIndex = aIndex/BLOCK_SIZE_BITS;
   1.152 +        if (blockIndex >= mBlocks.Length()) {
   1.153 +            nsAutoPtr<Block> *blocks = mBlocks.AppendElements(blockIndex + 1 - mBlocks.Length());
   1.154 +            if (MOZ_UNLIKELY(!blocks)) // OOM
   1.155 +                return;
   1.156 +        }
   1.157 +        Block *block = mBlocks[blockIndex];
   1.158 +        if (!block) {
   1.159 +            block = new Block;
   1.160 +            mBlocks[blockIndex] = block;
   1.161 +        }
   1.162 +        block->mBits[(aIndex>>3) & (BLOCK_SIZE - 1)] |= 1 << (aIndex & 0x7);
   1.163 +    }
   1.164 +
   1.165 +    void set(uint32_t aIndex, bool aValue) {
   1.166 +        if (aValue)
   1.167 +            set(aIndex);
   1.168 +        else
   1.169 +            clear(aIndex);
   1.170 +    }
   1.171 +
   1.172 +    void SetRange(uint32_t aStart, uint32_t aEnd) {
   1.173 +        const uint32_t startIndex = aStart/BLOCK_SIZE_BITS;
   1.174 +        const uint32_t endIndex = aEnd/BLOCK_SIZE_BITS;
   1.175 +
   1.176 +        if (endIndex >= mBlocks.Length()) {
   1.177 +            uint32_t numNewBlocks = endIndex + 1 - mBlocks.Length();
   1.178 +            nsAutoPtr<Block> *blocks = mBlocks.AppendElements(numNewBlocks);
   1.179 +            if (MOZ_UNLIKELY(!blocks)) // OOM
   1.180 +                return;
   1.181 +        }
   1.182 +
   1.183 +        for (uint32_t i = startIndex; i <= endIndex; ++i) {
   1.184 +            const uint32_t blockFirstBit = i * BLOCK_SIZE_BITS;
   1.185 +            const uint32_t blockLastBit = blockFirstBit + BLOCK_SIZE_BITS - 1;
   1.186 +
   1.187 +            Block *block = mBlocks[i];
   1.188 +            if (!block) {
   1.189 +                bool fullBlock = false;
   1.190 +                if (aStart <= blockFirstBit && aEnd >= blockLastBit)
   1.191 +                    fullBlock = true;
   1.192 +
   1.193 +                block = new Block(fullBlock ? 0xFF : 0);
   1.194 +                mBlocks[i] = block;
   1.195 +
   1.196 +                if (fullBlock)
   1.197 +                    continue;
   1.198 +            }
   1.199 +
   1.200 +            const uint32_t start = aStart > blockFirstBit ? aStart - blockFirstBit : 0;
   1.201 +            const uint32_t end = std::min<uint32_t>(aEnd - blockFirstBit, BLOCK_SIZE_BITS - 1);
   1.202 +
   1.203 +            for (uint32_t bit = start; bit <= end; ++bit) {
   1.204 +                block->mBits[bit>>3] |= 1 << (bit & 0x7);
   1.205 +            }
   1.206 +        }
   1.207 +    }
   1.208 +
   1.209 +    void clear(uint32_t aIndex) {
   1.210 +        uint32_t blockIndex = aIndex/BLOCK_SIZE_BITS;
   1.211 +        if (blockIndex >= mBlocks.Length()) {
   1.212 +            nsAutoPtr<Block> *blocks = mBlocks.AppendElements(blockIndex + 1 - mBlocks.Length());
   1.213 +            if (MOZ_UNLIKELY(!blocks)) // OOM
   1.214 +                return;
   1.215 +        }
   1.216 +        Block *block = mBlocks[blockIndex];
   1.217 +        if (!block) {
   1.218 +            return;
   1.219 +        }
   1.220 +        block->mBits[(aIndex>>3) & (BLOCK_SIZE - 1)] &= ~(1 << (aIndex & 0x7));
   1.221 +    }
   1.222 +
   1.223 +    void ClearRange(uint32_t aStart, uint32_t aEnd) {
   1.224 +        const uint32_t startIndex = aStart/BLOCK_SIZE_BITS;
   1.225 +        const uint32_t endIndex = aEnd/BLOCK_SIZE_BITS;
   1.226 +
   1.227 +        if (endIndex >= mBlocks.Length()) {
   1.228 +            uint32_t numNewBlocks = endIndex + 1 - mBlocks.Length();
   1.229 +            nsAutoPtr<Block> *blocks = mBlocks.AppendElements(numNewBlocks);
   1.230 +            if (MOZ_UNLIKELY(!blocks)) // OOM
   1.231 +                return;
   1.232 +        }
   1.233 +
   1.234 +        for (uint32_t i = startIndex; i <= endIndex; ++i) {
   1.235 +            const uint32_t blockFirstBit = i * BLOCK_SIZE_BITS;
   1.236 +
   1.237 +            Block *block = mBlocks[i];
   1.238 +            if (!block) {
   1.239 +                // any nonexistent block is implicitly all clear,
   1.240 +                // so there's no need to even create it
   1.241 +                continue;
   1.242 +            }
   1.243 +
   1.244 +            const uint32_t start = aStart > blockFirstBit ? aStart - blockFirstBit : 0;
   1.245 +            const uint32_t end = std::min<uint32_t>(aEnd - blockFirstBit, BLOCK_SIZE_BITS - 1);
   1.246 +
   1.247 +            for (uint32_t bit = start; bit <= end; ++bit) {
   1.248 +                block->mBits[bit>>3] &= ~(1 << (bit & 0x7));
   1.249 +            }
   1.250 +        }
   1.251 +    }
   1.252 +
   1.253 +    size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
   1.254 +        size_t total = mBlocks.SizeOfExcludingThis(aMallocSizeOf);
   1.255 +        for (uint32_t i = 0; i < mBlocks.Length(); i++) {
   1.256 +            if (mBlocks[i]) {
   1.257 +                total += aMallocSizeOf(mBlocks[i]);
   1.258 +            }
   1.259 +        }
   1.260 +        return total;
   1.261 +    }
   1.262 +
   1.263 +    size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
   1.264 +        return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   1.265 +    }
   1.266 +
   1.267 +    // clear out all blocks in the array
   1.268 +    void reset() {
   1.269 +        uint32_t i;
   1.270 +        for (i = 0; i < mBlocks.Length(); i++)
   1.271 +            mBlocks[i] = nullptr;    
   1.272 +    }
   1.273 +
   1.274 +    // set this bitset to the union of its current contents and another
   1.275 +    void Union(const gfxSparseBitSet& aBitset) {
   1.276 +        // ensure mBlocks is large enough
   1.277 +        uint32_t blockCount = aBitset.mBlocks.Length();
   1.278 +        if (blockCount > mBlocks.Length()) {
   1.279 +            uint32_t needed = blockCount - mBlocks.Length();
   1.280 +            nsAutoPtr<Block> *blocks = mBlocks.AppendElements(needed);
   1.281 +            if (MOZ_UNLIKELY(!blocks)) { // OOM
   1.282 +                return;
   1.283 +            }
   1.284 +        }
   1.285 +        // for each block that may be present in aBitset...
   1.286 +        for (uint32_t i = 0; i < blockCount; ++i) {
   1.287 +            // if it is missing (implicitly empty), just skip
   1.288 +            if (!aBitset.mBlocks[i]) {
   1.289 +                continue;
   1.290 +            }
   1.291 +            // if the block is missing in this set, just copy the other
   1.292 +            if (!mBlocks[i]) {
   1.293 +                mBlocks[i] = new Block(*aBitset.mBlocks[i]);
   1.294 +                continue;
   1.295 +            }
   1.296 +            // else set existing block to the union of both
   1.297 +            uint32_t *dst = reinterpret_cast<uint32_t*>(mBlocks[i]->mBits);
   1.298 +            const uint32_t *src =
   1.299 +                reinterpret_cast<const uint32_t*>(aBitset.mBlocks[i]->mBits);
   1.300 +            for (uint32_t j = 0; j < BLOCK_SIZE / 4; ++j) {
   1.301 +                dst[j] |= src[j];
   1.302 +            }
   1.303 +        }
   1.304 +    }
   1.305 +
   1.306 +    void Compact() {
   1.307 +        mBlocks.Compact();
   1.308 +    }
   1.309 +
   1.310 +    uint32_t GetChecksum() const {
   1.311 +        uint32_t check = adler32(0, Z_NULL, 0);
   1.312 +        for (uint32_t i = 0; i < mBlocks.Length(); i++) {
   1.313 +            if (mBlocks[i]) {
   1.314 +                const Block *block = mBlocks[i];
   1.315 +                check = adler32(check, (uint8_t*) (&i), 4);
   1.316 +                check = adler32(check, (uint8_t*) block, sizeof(Block));
   1.317 +            }
   1.318 +        }
   1.319 +        return check;
   1.320 +    }
   1.321 +
   1.322 +private:
   1.323 +    nsTArray< nsAutoPtr<Block> > mBlocks;
   1.324 +};
   1.325 +
   1.326 +#define TRUETYPE_TAG(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
   1.327 +
   1.328 +namespace mozilla {
   1.329 +
   1.330 +// Byte-swapping types and name table structure definitions moved from
   1.331 +// gfxFontUtils.cpp to .h file so that gfxFont.cpp can also refer to them
   1.332 +#pragma pack(1)
   1.333 +
   1.334 +struct AutoSwap_PRUint16 {
   1.335 +#ifdef __SUNPRO_CC
   1.336 +    AutoSwap_PRUint16& operator = (const uint16_t aValue)
   1.337 +    {
   1.338 +        this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.339 +        return *this;
   1.340 +    }
   1.341 +#else
   1.342 +    AutoSwap_PRUint16(uint16_t aValue)
   1.343 +    {
   1.344 +        value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.345 +    }
   1.346 +#endif
   1.347 +    operator uint16_t() const
   1.348 +    {
   1.349 +        return mozilla::NativeEndian::swapFromBigEndian(value);
   1.350 +    }
   1.351 +
   1.352 +    operator uint32_t() const
   1.353 +    {
   1.354 +        return mozilla::NativeEndian::swapFromBigEndian(value);
   1.355 +    }
   1.356 +
   1.357 +    operator uint64_t() const
   1.358 +    {
   1.359 +        return mozilla::NativeEndian::swapFromBigEndian(value);
   1.360 +    }
   1.361 +
   1.362 +private:
   1.363 +    uint16_t value;
   1.364 +};
   1.365 +
   1.366 +struct AutoSwap_PRInt16 {
   1.367 +#ifdef __SUNPRO_CC
   1.368 +    AutoSwap_PRInt16& operator = (const int16_t aValue)
   1.369 +    {
   1.370 +        this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.371 +        return *this;
   1.372 +    }
   1.373 +#else
   1.374 +    AutoSwap_PRInt16(int16_t aValue)
   1.375 +    {
   1.376 +        value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.377 +    }
   1.378 +#endif
   1.379 +    operator int16_t() const
   1.380 +    {
   1.381 +        return mozilla::NativeEndian::swapFromBigEndian(value);
   1.382 +    }
   1.383 +
   1.384 +    operator uint32_t() const
   1.385 +    {
   1.386 +        return mozilla::NativeEndian::swapFromBigEndian(value);
   1.387 +    }
   1.388 +
   1.389 +private:
   1.390 +    int16_t  value;
   1.391 +};
   1.392 +
   1.393 +struct AutoSwap_PRUint32 {
   1.394 +#ifdef __SUNPRO_CC
   1.395 +    AutoSwap_PRUint32& operator = (const uint32_t aValue)
   1.396 +    {
   1.397 +        this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.398 +        return *this;
   1.399 +    }
   1.400 +#else
   1.401 +    AutoSwap_PRUint32(uint32_t aValue)
   1.402 +    {
   1.403 +        value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.404 +    }
   1.405 +#endif
   1.406 +    operator uint32_t() const
   1.407 +    {
   1.408 +        return mozilla::NativeEndian::swapFromBigEndian(value);
   1.409 +    }
   1.410 +
   1.411 +private:
   1.412 +    uint32_t  value;
   1.413 +};
   1.414 +
   1.415 +struct AutoSwap_PRInt32 {
   1.416 +#ifdef __SUNPRO_CC
   1.417 +    AutoSwap_PRInt32& operator = (const int32_t aValue)
   1.418 +    {
   1.419 +        this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.420 +        return *this;
   1.421 +    }
   1.422 +#else
   1.423 +    AutoSwap_PRInt32(int32_t aValue)
   1.424 +    {
   1.425 +        value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.426 +    }
   1.427 +#endif
   1.428 +    operator int32_t() const
   1.429 +    {
   1.430 +        return mozilla::NativeEndian::swapFromBigEndian(value);
   1.431 +    }
   1.432 +
   1.433 +private:
   1.434 +    int32_t  value;
   1.435 +};
   1.436 +
   1.437 +struct AutoSwap_PRUint64 {
   1.438 +#ifdef __SUNPRO_CC
   1.439 +    AutoSwap_PRUint64& operator = (const uint64_t aValue)
   1.440 +    {
   1.441 +        this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.442 +        return *this;
   1.443 +    }
   1.444 +#else
   1.445 +    AutoSwap_PRUint64(uint64_t aValue)
   1.446 +    {
   1.447 +        value = mozilla::NativeEndian::swapToBigEndian(aValue);
   1.448 +    }
   1.449 +#endif
   1.450 +    operator uint64_t() const
   1.451 +    {
   1.452 +        return mozilla::NativeEndian::swapFromBigEndian(value);
   1.453 +    }
   1.454 +
   1.455 +private:
   1.456 +    uint64_t  value;
   1.457 +};
   1.458 +
   1.459 +struct AutoSwap_PRUint24 {
   1.460 +    operator uint32_t() const { return value[0] << 16 | value[1] << 8 | value[2]; }
   1.461 +private:
   1.462 +    AutoSwap_PRUint24() { }
   1.463 +    uint8_t  value[3];
   1.464 +};
   1.465 +
   1.466 +struct SFNTHeader {
   1.467 +    AutoSwap_PRUint32    sfntVersion;            // Fixed, 0x00010000 for version 1.0.
   1.468 +    AutoSwap_PRUint16    numTables;              // Number of tables.
   1.469 +    AutoSwap_PRUint16    searchRange;            // (Maximum power of 2 <= numTables) x 16.
   1.470 +    AutoSwap_PRUint16    entrySelector;          // Log2(maximum power of 2 <= numTables).
   1.471 +    AutoSwap_PRUint16    rangeShift;             // NumTables x 16-searchRange.        
   1.472 +};
   1.473 +
   1.474 +struct TableDirEntry {
   1.475 +    AutoSwap_PRUint32    tag;                    // 4 -byte identifier.
   1.476 +    AutoSwap_PRUint32    checkSum;               // CheckSum for this table.
   1.477 +    AutoSwap_PRUint32    offset;                 // Offset from beginning of TrueType font file.
   1.478 +    AutoSwap_PRUint32    length;                 // Length of this table.        
   1.479 +};
   1.480 +
   1.481 +struct HeadTable {
   1.482 +    enum {
   1.483 +        HEAD_VERSION = 0x00010000,
   1.484 +        HEAD_MAGIC_NUMBER = 0x5F0F3CF5,
   1.485 +        HEAD_CHECKSUM_CALC_CONST = 0xB1B0AFBA
   1.486 +    };
   1.487 +
   1.488 +    AutoSwap_PRUint32    tableVersionNumber;    // Fixed, 0x00010000 for version 1.0.
   1.489 +    AutoSwap_PRUint32    fontRevision;          // Set by font manufacturer.
   1.490 +    AutoSwap_PRUint32    checkSumAdjustment;    // To compute: set it to 0, sum the entire font as ULONG, then store 0xB1B0AFBA - sum.
   1.491 +    AutoSwap_PRUint32    magicNumber;           // Set to 0x5F0F3CF5.
   1.492 +    AutoSwap_PRUint16    flags;
   1.493 +    AutoSwap_PRUint16    unitsPerEm;            // Valid range is from 16 to 16384. This value should be a power of 2 for fonts that have TrueType outlines.
   1.494 +    AutoSwap_PRUint64    created;               // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
   1.495 +    AutoSwap_PRUint64    modified;              // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
   1.496 +    AutoSwap_PRInt16     xMin;                  // For all glyph bounding boxes.
   1.497 +    AutoSwap_PRInt16     yMin;                  // For all glyph bounding boxes.
   1.498 +    AutoSwap_PRInt16     xMax;                  // For all glyph bounding boxes.
   1.499 +    AutoSwap_PRInt16     yMax;                  // For all glyph bounding boxes.
   1.500 +    AutoSwap_PRUint16    macStyle;              // Bit 0: Bold (if set to 1);
   1.501 +    AutoSwap_PRUint16    lowestRecPPEM;         // Smallest readable size in pixels.
   1.502 +    AutoSwap_PRInt16     fontDirectionHint;
   1.503 +    AutoSwap_PRInt16     indexToLocFormat;
   1.504 +    AutoSwap_PRInt16     glyphDataFormat;
   1.505 +};
   1.506 +
   1.507 +struct OS2Table {
   1.508 +    AutoSwap_PRUint16    version;                // 0004 = OpenType 1.5
   1.509 +    AutoSwap_PRInt16     xAvgCharWidth;
   1.510 +    AutoSwap_PRUint16    usWeightClass;
   1.511 +    AutoSwap_PRUint16    usWidthClass;
   1.512 +    AutoSwap_PRUint16    fsType;
   1.513 +    AutoSwap_PRInt16     ySubscriptXSize;
   1.514 +    AutoSwap_PRInt16     ySubscriptYSize;
   1.515 +    AutoSwap_PRInt16     ySubscriptXOffset;
   1.516 +    AutoSwap_PRInt16     ySubscriptYOffset;
   1.517 +    AutoSwap_PRInt16     ySuperscriptXSize;
   1.518 +    AutoSwap_PRInt16     ySuperscriptYSize;
   1.519 +    AutoSwap_PRInt16     ySuperscriptXOffset;
   1.520 +    AutoSwap_PRInt16     ySuperscriptYOffset;
   1.521 +    AutoSwap_PRInt16     yStrikeoutSize;
   1.522 +    AutoSwap_PRInt16     yStrikeoutPosition;
   1.523 +    AutoSwap_PRInt16     sFamilyClass;
   1.524 +    uint8_t              panose[10];
   1.525 +    AutoSwap_PRUint32    unicodeRange1;
   1.526 +    AutoSwap_PRUint32    unicodeRange2;
   1.527 +    AutoSwap_PRUint32    unicodeRange3;
   1.528 +    AutoSwap_PRUint32    unicodeRange4;
   1.529 +    uint8_t              achVendID[4];
   1.530 +    AutoSwap_PRUint16    fsSelection;
   1.531 +    AutoSwap_PRUint16    usFirstCharIndex;
   1.532 +    AutoSwap_PRUint16    usLastCharIndex;
   1.533 +    AutoSwap_PRInt16     sTypoAscender;
   1.534 +    AutoSwap_PRInt16     sTypoDescender;
   1.535 +    AutoSwap_PRInt16     sTypoLineGap;
   1.536 +    AutoSwap_PRUint16    usWinAscent;
   1.537 +    AutoSwap_PRUint16    usWinDescent;
   1.538 +    AutoSwap_PRUint32    codePageRange1;
   1.539 +    AutoSwap_PRUint32    codePageRange2;
   1.540 +    AutoSwap_PRInt16     sxHeight;
   1.541 +    AutoSwap_PRInt16     sCapHeight;
   1.542 +    AutoSwap_PRUint16    usDefaultChar;
   1.543 +    AutoSwap_PRUint16    usBreakChar;
   1.544 +    AutoSwap_PRUint16    usMaxContext;
   1.545 +};
   1.546 +
   1.547 +struct PostTable {
   1.548 +    AutoSwap_PRUint32    version;
   1.549 +    AutoSwap_PRInt32     italicAngle;
   1.550 +    AutoSwap_PRInt16     underlinePosition;
   1.551 +    AutoSwap_PRUint16    underlineThickness;
   1.552 +    AutoSwap_PRUint32    isFixedPitch;
   1.553 +    AutoSwap_PRUint32    minMemType42;
   1.554 +    AutoSwap_PRUint32    maxMemType42;
   1.555 +    AutoSwap_PRUint32    minMemType1;
   1.556 +    AutoSwap_PRUint32    maxMemType1;
   1.557 +};
   1.558 +
   1.559 +struct HheaTable {
   1.560 +    AutoSwap_PRUint32    version;
   1.561 +    AutoSwap_PRInt16     ascender;
   1.562 +    AutoSwap_PRInt16     descender;
   1.563 +    AutoSwap_PRInt16     lineGap;
   1.564 +    AutoSwap_PRUint16    advanceWidthMax;
   1.565 +    AutoSwap_PRInt16     minLeftSideBearing;
   1.566 +    AutoSwap_PRInt16     minRightSideBearing;
   1.567 +    AutoSwap_PRInt16     xMaxExtent;
   1.568 +    AutoSwap_PRInt16     caretSlopeRise;
   1.569 +    AutoSwap_PRInt16     caretSlopeRun;
   1.570 +    AutoSwap_PRInt16     caretOffset;
   1.571 +    AutoSwap_PRInt16     reserved1;
   1.572 +    AutoSwap_PRInt16     reserved2;
   1.573 +    AutoSwap_PRInt16     reserved3;
   1.574 +    AutoSwap_PRInt16     reserved4;
   1.575 +    AutoSwap_PRInt16     metricDataFormat;
   1.576 +    AutoSwap_PRUint16    numOfLongHorMetrics;
   1.577 +};
   1.578 +
   1.579 +struct MaxpTableHeader {
   1.580 +    AutoSwap_PRUint32    version; // CFF: 0x00005000; TrueType: 0x00010000
   1.581 +    AutoSwap_PRUint16    numGlyphs;
   1.582 +// truetype version has additional fields that we don't currently use
   1.583 +};
   1.584 +
   1.585 +// old 'kern' table, supported on Windows
   1.586 +// see http://www.microsoft.com/typography/otspec/kern.htm
   1.587 +struct KernTableVersion0 {
   1.588 +    AutoSwap_PRUint16    version; // 0x0000
   1.589 +    AutoSwap_PRUint16    nTables;
   1.590 +};
   1.591 +
   1.592 +struct KernTableSubtableHeaderVersion0 {
   1.593 +    AutoSwap_PRUint16    version;
   1.594 +    AutoSwap_PRUint16    length;
   1.595 +    AutoSwap_PRUint16    coverage;
   1.596 +};
   1.597 +
   1.598 +// newer Mac-only 'kern' table, ignored by Windows
   1.599 +// see http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6kern.html
   1.600 +struct KernTableVersion1 {
   1.601 +    AutoSwap_PRUint32    version; // 0x00010000
   1.602 +    AutoSwap_PRUint32    nTables;
   1.603 +};
   1.604 +
   1.605 +struct KernTableSubtableHeaderVersion1 {
   1.606 +    AutoSwap_PRUint32    length;
   1.607 +    AutoSwap_PRUint16    coverage;
   1.608 +    AutoSwap_PRUint16    tupleIndex;
   1.609 +};
   1.610 +
   1.611 +#pragma pack()
   1.612 +
   1.613 +// Return just the highest bit of the given value, i.e., the highest
   1.614 +// power of 2 that is <= value, or zero if the input value is zero.
   1.615 +inline uint32_t
   1.616 +FindHighestBit(uint32_t value)
   1.617 +{
   1.618 +    // propagate highest bit into all lower bits of the value
   1.619 +    value |= (value >> 1);
   1.620 +    value |= (value >> 2);
   1.621 +    value |= (value >> 4);
   1.622 +    value |= (value >> 8);
   1.623 +    value |= (value >> 16);
   1.624 +    // isolate the leftmost bit
   1.625 +    return (value & ~(value >> 1));
   1.626 +}
   1.627 +
   1.628 +} // namespace mozilla
   1.629 +
   1.630 +// used for overlaying name changes without touching original font data
   1.631 +struct FontDataOverlay {
   1.632 +    // overlaySrc != 0 ==> use overlay
   1.633 +    uint32_t  overlaySrc;    // src offset from start of font data
   1.634 +    uint32_t  overlaySrcLen; // src length
   1.635 +    uint32_t  overlayDest;   // dest offset from start of font data
   1.636 +};
   1.637 +    
   1.638 +enum gfxUserFontType {
   1.639 +    GFX_USERFONT_UNKNOWN = 0,
   1.640 +    GFX_USERFONT_OPENTYPE = 1,
   1.641 +    GFX_USERFONT_SVG = 2,
   1.642 +    GFX_USERFONT_WOFF = 3
   1.643 +};
   1.644 +
   1.645 +extern const uint8_t sCJKCompatSVSTable[];
   1.646 +
   1.647 +class gfxFontUtils {
   1.648 +
   1.649 +public:
   1.650 +    // these are public because gfxFont.cpp also looks into the name table
   1.651 +    enum {
   1.652 +        NAME_ID_FAMILY = 1,
   1.653 +        NAME_ID_STYLE = 2,
   1.654 +        NAME_ID_UNIQUE = 3,
   1.655 +        NAME_ID_FULL = 4,
   1.656 +        NAME_ID_VERSION = 5,
   1.657 +        NAME_ID_POSTSCRIPT = 6,
   1.658 +        NAME_ID_PREFERRED_FAMILY = 16,
   1.659 +        NAME_ID_PREFERRED_STYLE = 17,
   1.660 +
   1.661 +        PLATFORM_ALL = -1,
   1.662 +        PLATFORM_ID_UNICODE = 0,           // Mac OS uses this typically
   1.663 +        PLATFORM_ID_MAC = 1,
   1.664 +        PLATFORM_ID_ISO = 2,
   1.665 +        PLATFORM_ID_MICROSOFT = 3,
   1.666 +
   1.667 +        ENCODING_ID_MAC_ROMAN = 0,         // traditional Mac OS script manager encodings
   1.668 +        ENCODING_ID_MAC_JAPANESE = 1,      // (there are others defined, but some were never
   1.669 +        ENCODING_ID_MAC_TRAD_CHINESE = 2,  // implemented by Apple, and I have never seen them
   1.670 +        ENCODING_ID_MAC_KOREAN = 3,        // used in font names)
   1.671 +        ENCODING_ID_MAC_ARABIC = 4,
   1.672 +        ENCODING_ID_MAC_HEBREW = 5,
   1.673 +        ENCODING_ID_MAC_GREEK = 6,
   1.674 +        ENCODING_ID_MAC_CYRILLIC = 7,
   1.675 +        ENCODING_ID_MAC_DEVANAGARI = 9,
   1.676 +        ENCODING_ID_MAC_GURMUKHI = 10,
   1.677 +        ENCODING_ID_MAC_GUJARATI = 11,
   1.678 +        ENCODING_ID_MAC_SIMP_CHINESE = 25,
   1.679 +
   1.680 +        ENCODING_ID_MICROSOFT_SYMBOL = 0,  // Microsoft platform encoding IDs
   1.681 +        ENCODING_ID_MICROSOFT_UNICODEBMP = 1,
   1.682 +        ENCODING_ID_MICROSOFT_SHIFTJIS = 2,
   1.683 +        ENCODING_ID_MICROSOFT_PRC = 3,
   1.684 +        ENCODING_ID_MICROSOFT_BIG5 = 4,
   1.685 +        ENCODING_ID_MICROSOFT_WANSUNG = 5,
   1.686 +        ENCODING_ID_MICROSOFT_JOHAB  = 6,
   1.687 +        ENCODING_ID_MICROSOFT_UNICODEFULL = 10,
   1.688 +
   1.689 +        LANG_ALL = -1,
   1.690 +        LANG_ID_MAC_ENGLISH = 0,      // many others are defined, but most don't affect
   1.691 +        LANG_ID_MAC_HEBREW = 10,      // the charset; should check all the central/eastern
   1.692 +        LANG_ID_MAC_JAPANESE = 11,    // european codes, though
   1.693 +        LANG_ID_MAC_ARABIC = 12,
   1.694 +        LANG_ID_MAC_ICELANDIC = 15,
   1.695 +        LANG_ID_MAC_TURKISH = 17,
   1.696 +        LANG_ID_MAC_TRAD_CHINESE = 19,
   1.697 +        LANG_ID_MAC_URDU = 20,
   1.698 +        LANG_ID_MAC_KOREAN = 23,
   1.699 +        LANG_ID_MAC_POLISH = 25,
   1.700 +        LANG_ID_MAC_FARSI = 31,
   1.701 +        LANG_ID_MAC_SIMP_CHINESE = 33,
   1.702 +        LANG_ID_MAC_ROMANIAN = 37,
   1.703 +        LANG_ID_MAC_CZECH = 38,
   1.704 +        LANG_ID_MAC_SLOVAK = 39,
   1.705 +
   1.706 +        LANG_ID_MICROSOFT_EN_US = 0x0409,        // with Microsoft platformID, EN US lang code
   1.707 +        
   1.708 +        CMAP_MAX_CODEPOINT = 0x10ffff     // maximum possible Unicode codepoint 
   1.709 +                                          // contained in a cmap
   1.710 +    };
   1.711 +
   1.712 +    // name table has a header, followed by name records, followed by string data
   1.713 +    struct NameHeader {
   1.714 +        mozilla::AutoSwap_PRUint16    format;       // Format selector (=0).
   1.715 +        mozilla::AutoSwap_PRUint16    count;        // Number of name records.
   1.716 +        mozilla::AutoSwap_PRUint16    stringOffset; // Offset to start of string storage
   1.717 +                                                    // (from start of table)
   1.718 +    };
   1.719 +
   1.720 +    struct NameRecord {
   1.721 +        mozilla::AutoSwap_PRUint16    platformID;   // Platform ID
   1.722 +        mozilla::AutoSwap_PRUint16    encodingID;   // Platform-specific encoding ID
   1.723 +        mozilla::AutoSwap_PRUint16    languageID;   // Language ID
   1.724 +        mozilla::AutoSwap_PRUint16    nameID;       // Name ID.
   1.725 +        mozilla::AutoSwap_PRUint16    length;       // String length (in bytes).
   1.726 +        mozilla::AutoSwap_PRUint16    offset;       // String offset from start of storage
   1.727 +                                                    // (in bytes).
   1.728 +    };
   1.729 +
   1.730 +    // for reading big-endian font data on either big or little-endian platforms
   1.731 +
   1.732 +    static inline uint16_t
   1.733 +    ReadShortAt(const uint8_t *aBuf, uint32_t aIndex)
   1.734 +    {
   1.735 +        return (aBuf[aIndex] << 8) | aBuf[aIndex + 1];
   1.736 +    }
   1.737 +
   1.738 +    static inline uint16_t
   1.739 +    ReadShortAt16(const uint16_t *aBuf, uint32_t aIndex)
   1.740 +    {
   1.741 +        const uint8_t *buf = reinterpret_cast<const uint8_t*>(aBuf);
   1.742 +        uint32_t index = aIndex << 1;
   1.743 +        return (buf[index] << 8) | buf[index+1];
   1.744 +    }
   1.745 +
   1.746 +    static inline uint32_t
   1.747 +    ReadUint24At(const uint8_t *aBuf, uint32_t aIndex)
   1.748 +    {
   1.749 +        return ((aBuf[aIndex] << 16) | (aBuf[aIndex + 1] << 8) |
   1.750 +                (aBuf[aIndex + 2]));
   1.751 +    }
   1.752 +
   1.753 +    static inline uint32_t
   1.754 +    ReadLongAt(const uint8_t *aBuf, uint32_t aIndex)
   1.755 +    {
   1.756 +        return ((aBuf[aIndex] << 24) | (aBuf[aIndex + 1] << 16) | 
   1.757 +                (aBuf[aIndex + 2] << 8) | (aBuf[aIndex + 3]));
   1.758 +    }
   1.759 +
   1.760 +    static nsresult
   1.761 +    ReadCMAPTableFormat12(const uint8_t *aBuf, uint32_t aLength, 
   1.762 +                          gfxSparseBitSet& aCharacterMap);
   1.763 +
   1.764 +    static nsresult 
   1.765 +    ReadCMAPTableFormat4(const uint8_t *aBuf, uint32_t aLength, 
   1.766 +                         gfxSparseBitSet& aCharacterMap);
   1.767 +
   1.768 +    static nsresult
   1.769 +    ReadCMAPTableFormat14(const uint8_t *aBuf, uint32_t aLength, 
   1.770 +                          uint8_t*& aTable);
   1.771 +
   1.772 +    static uint32_t
   1.773 +    FindPreferredSubtable(const uint8_t *aBuf, uint32_t aBufLength,
   1.774 +                          uint32_t *aTableOffset, uint32_t *aUVSTableOffset,
   1.775 +                          bool *aSymbolEncoding);
   1.776 +
   1.777 +    static nsresult
   1.778 +    ReadCMAP(const uint8_t *aBuf, uint32_t aBufLength,
   1.779 +             gfxSparseBitSet& aCharacterMap,
   1.780 +             uint32_t& aUVSOffset,
   1.781 +             bool& aUnicodeFont, bool& aSymbolFont);
   1.782 +
   1.783 +    static uint32_t
   1.784 +    MapCharToGlyphFormat4(const uint8_t *aBuf, char16_t aCh);
   1.785 +
   1.786 +    static uint32_t
   1.787 +    MapCharToGlyphFormat12(const uint8_t *aBuf, uint32_t aCh);
   1.788 +
   1.789 +    static uint16_t
   1.790 +    MapUVSToGlyphFormat14(const uint8_t *aBuf, uint32_t aCh, uint32_t aVS);
   1.791 +
   1.792 +    // sCJKCompatSVSTable is a 'cmap' format 14 subtable that maps
   1.793 +    // <char + var-selector> pairs to the corresponding Unicode
   1.794 +    // compatibility ideograph codepoints.
   1.795 +    static MOZ_ALWAYS_INLINE uint32_t
   1.796 +    GetUVSFallback(uint32_t aCh, uint32_t aVS) {
   1.797 +        aCh = MapUVSToGlyphFormat14(sCJKCompatSVSTable, aCh, aVS);
   1.798 +        return aCh >= 0xFB00 ? aCh + (0x2F800 - 0xFB00) : aCh;
   1.799 +    }
   1.800 +
   1.801 +    static uint32_t
   1.802 +    MapCharToGlyph(const uint8_t *aCmapBuf, uint32_t aBufLength,
   1.803 +                   uint32_t aUnicode, uint32_t aVarSelector = 0);
   1.804 +
   1.805 +#ifdef XP_WIN
   1.806 +    // determine whether a font (which has already been sanitized, so is known
   1.807 +    // to be a valid sfnt) is CFF format rather than TrueType
   1.808 +    static bool
   1.809 +    IsCffFont(const uint8_t* aFontData);
   1.810 +#endif
   1.811 +
   1.812 +    // determine the format of font data
   1.813 +    static gfxUserFontType
   1.814 +    DetermineFontDataType(const uint8_t *aFontData, uint32_t aFontDataLength);
   1.815 +
   1.816 +    // Read the fullname from the sfnt data (used to save the original name
   1.817 +    // prior to renaming the font for installation).
   1.818 +    // This is called with sfnt data that has already been validated,
   1.819 +    // so it should always succeed in finding the name table.
   1.820 +    static nsresult
   1.821 +    GetFullNameFromSFNT(const uint8_t* aFontData, uint32_t aLength,
   1.822 +                        nsAString& aFullName);
   1.823 +
   1.824 +    // helper to get fullname from name table, constructing from family+style
   1.825 +    // if no explicit fullname is present
   1.826 +    static nsresult
   1.827 +    GetFullNameFromTable(hb_blob_t *aNameTable,
   1.828 +                         nsAString& aFullName);
   1.829 +
   1.830 +    // helper to get family name from name table
   1.831 +    static nsresult
   1.832 +    GetFamilyNameFromTable(hb_blob_t *aNameTable,
   1.833 +                           nsAString& aFamilyName);
   1.834 +
   1.835 +    // create a new name table and build a new font with that name table
   1.836 +    // appended on the end, returns true on success
   1.837 +    static nsresult
   1.838 +    RenameFont(const nsAString& aName, const uint8_t *aFontData, 
   1.839 +               uint32_t aFontDataLength, FallibleTArray<uint8_t> *aNewFont);
   1.840 +    
   1.841 +    // read all names matching aNameID, returning in aNames array
   1.842 +    static nsresult
   1.843 +    ReadNames(const char *aNameData, uint32_t aDataLen, uint32_t aNameID,
   1.844 +              int32_t aPlatformID, nsTArray<nsString>& aNames);
   1.845 +
   1.846 +    // reads English or first name matching aNameID, returning in aName
   1.847 +    // platform based on OS
   1.848 +    static nsresult
   1.849 +    ReadCanonicalName(hb_blob_t *aNameTable, uint32_t aNameID,
   1.850 +                      nsString& aName);
   1.851 +
   1.852 +    static nsresult
   1.853 +    ReadCanonicalName(const char *aNameData, uint32_t aDataLen,
   1.854 +                      uint32_t aNameID, nsString& aName);
   1.855 +
   1.856 +    // convert a name from the raw name table data into an nsString,
   1.857 +    // provided we know how; return true if successful, or false
   1.858 +    // if we can't handle the encoding
   1.859 +    static bool
   1.860 +    DecodeFontName(const char *aBuf, int32_t aLength, 
   1.861 +                   uint32_t aPlatformCode, uint32_t aScriptCode,
   1.862 +                   uint32_t aLangCode, nsAString& dest);
   1.863 +
   1.864 +    static inline bool IsJoinCauser(uint32_t ch) {
   1.865 +        return (ch == 0x200D);
   1.866 +    }
   1.867 +
   1.868 +    static inline bool IsJoinControl(uint32_t ch) {
   1.869 +        return (ch == 0x200C || ch == 0x200D);
   1.870 +    }
   1.871 +
   1.872 +    enum {
   1.873 +        kUnicodeVS1 = 0xFE00,
   1.874 +        kUnicodeVS16 = 0xFE0F,
   1.875 +        kUnicodeVS17 = 0xE0100,
   1.876 +        kUnicodeVS256 = 0xE01EF
   1.877 +    };
   1.878 +
   1.879 +    static inline bool IsVarSelector(uint32_t ch) {
   1.880 +        return (ch >= kUnicodeVS1 && ch <= kUnicodeVS16) ||
   1.881 +               (ch >= kUnicodeVS17 && ch <= kUnicodeVS256);
   1.882 +    }
   1.883 +
   1.884 +    static inline bool IsInvalid(uint32_t ch) {
   1.885 +        return (ch == 0xFFFD);
   1.886 +    }
   1.887 +
   1.888 +    // Font code may want to know if there is the potential for bidi behavior
   1.889 +    // to be triggered by any of the characters in a text run; this can be
   1.890 +    // used to test that possibility.
   1.891 +    enum {
   1.892 +        kUnicodeBidiScriptsStart = 0x0590,
   1.893 +        kUnicodeBidiScriptsEnd = 0x08FF,
   1.894 +        kUnicodeBidiPresentationStart = 0xFB1D,
   1.895 +        kUnicodeBidiPresentationEnd = 0xFEFC,
   1.896 +        kUnicodeFirstHighSurrogateBlock = 0xD800,
   1.897 +        kUnicodeRLM = 0x200F,
   1.898 +        kUnicodeRLE = 0x202B,
   1.899 +        kUnicodeRLO = 0x202E
   1.900 +    };
   1.901 +
   1.902 +    static inline bool PotentialRTLChar(char16_t aCh) {
   1.903 +        if (aCh >= kUnicodeBidiScriptsStart && aCh <= kUnicodeBidiScriptsEnd)
   1.904 +            // bidi scripts Hebrew, Arabic, Syriac, Thaana, N'Ko are all encoded together
   1.905 +            return true;
   1.906 +
   1.907 +        if (aCh == kUnicodeRLM || aCh == kUnicodeRLE || aCh == kUnicodeRLO)
   1.908 +            // directional controls that trigger bidi layout
   1.909 +            return true;
   1.910 +
   1.911 +        if (aCh >= kUnicodeBidiPresentationStart &&
   1.912 +            aCh <= kUnicodeBidiPresentationEnd)
   1.913 +            // presentation forms of Arabic and Hebrew letters
   1.914 +            return true;
   1.915 +
   1.916 +        if ((aCh & 0xFF00) == kUnicodeFirstHighSurrogateBlock)
   1.917 +            // surrogate that could be part of a bidi supplementary char
   1.918 +            // (Cypriot, Aramaic, Phoenecian, etc)
   1.919 +            return true;
   1.920 +
   1.921 +        // otherwise we know this char cannot trigger bidi reordering
   1.922 +        return false;
   1.923 +    }
   1.924 +    
   1.925 +    // for a given font list pref name, set up a list of font names
   1.926 +    static void GetPrefsFontList(const char *aPrefName, 
   1.927 +                                 nsTArray<nsString>& aFontList);
   1.928 +
   1.929 +    // generate a unique font name
   1.930 +    static nsresult MakeUniqueUserFontName(nsAString& aName);
   1.931 +
   1.932 +protected:
   1.933 +    static nsresult
   1.934 +    ReadNames(const char *aNameData, uint32_t aDataLen, uint32_t aNameID,
   1.935 +              int32_t aLangID, int32_t aPlatformID, nsTArray<nsString>& aNames);
   1.936 +
   1.937 +    // convert opentype name-table platform/encoding/language values to a charset name
   1.938 +    // we can use to convert the name data to unicode, or "" if data is UTF16BE
   1.939 +    static const char*
   1.940 +    GetCharsetForFontName(uint16_t aPlatform, uint16_t aScript, uint16_t aLanguage);
   1.941 +
   1.942 +    struct MacFontNameCharsetMapping {
   1.943 +        uint16_t    mEncoding;
   1.944 +        uint16_t    mLanguage;
   1.945 +        const char *mCharsetName;
   1.946 +
   1.947 +        bool operator<(const MacFontNameCharsetMapping& rhs) const {
   1.948 +            return (mEncoding < rhs.mEncoding) ||
   1.949 +                   ((mEncoding == rhs.mEncoding) && (mLanguage < rhs.mLanguage));
   1.950 +        }
   1.951 +    };
   1.952 +    static const MacFontNameCharsetMapping gMacFontNameCharsets[];
   1.953 +    static const char* gISOFontNameCharsets[];
   1.954 +    static const char* gMSFontNameCharsets[];
   1.955 +};
   1.956 +
   1.957 +
   1.958 +#endif /* GFX_FONT_UTILS_H */

mercurial