LCOV - code coverage report
Current view: top level - gfx/thebes - gfxFontUtils.h (source / functions) Hit Total Coverage
Test: output.info Lines: 34 151 22.5 %
Date: 2017-07-14 16:53:18 Functions: 8 33 24.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef GFX_FONT_UTILS_H
       7             : #define GFX_FONT_UTILS_H
       8             : 
       9             : #include "gfxPlatform.h"
      10             : #include "nsComponentManagerUtils.h"
      11             : #include "nsTArray.h"
      12             : #include "mozilla/Likely.h"
      13             : #include "mozilla/EndianUtils.h"
      14             : #include "mozilla/MemoryReporting.h"
      15             : #include "mozilla/UniquePtr.h"
      16             : 
      17             : #include "zlib.h"
      18             : #include <algorithm>
      19             : 
      20             : /* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
      21             : #ifdef __MINGW32__
      22             : #undef min
      23             : #undef max
      24             : #endif
      25             : 
      26             : typedef struct hb_blob_t hb_blob_t;
      27             : 
      28           0 : class gfxSparseBitSet {
      29             : private:
      30             :     enum { BLOCK_SIZE = 32 };   // ==> 256 codepoints per block
      31             :     enum { BLOCK_SIZE_BITS = BLOCK_SIZE * 8 };
      32             :     enum { BLOCK_INDEX_SHIFT = 8 };
      33             : 
      34             :     struct Block {
      35           0 :         Block(const Block& aBlock) { memcpy(mBits, aBlock.mBits, sizeof(mBits)); }
      36           3 :         explicit Block(unsigned char memsetValue = 0) { memset(mBits, memsetValue, BLOCK_SIZE); }
      37             :         uint8_t mBits[BLOCK_SIZE];
      38             :     };
      39             : 
      40             : public:
      41         561 :     gfxSparseBitSet() { }
      42             :     gfxSparseBitSet(const gfxSparseBitSet& aBitset) {
      43             :         uint32_t len = aBitset.mBlocks.Length();
      44             :         mBlocks.AppendElements(len);
      45             :         for (uint32_t i = 0; i < len; ++i) {
      46             :             Block *block = aBitset.mBlocks[i].get();
      47             :             if (block) {
      48             :                 mBlocks[i] = mozilla::MakeUnique<Block>(*block);
      49             :             }
      50             :         }
      51             :     }
      52             : 
      53           0 :     bool Equals(const gfxSparseBitSet *aOther) const {
      54           0 :         if (mBlocks.Length() != aOther->mBlocks.Length()) {
      55           0 :             return false;
      56             :         }
      57           0 :         size_t n = mBlocks.Length();
      58           0 :         for (size_t i = 0; i < n; ++i) {
      59           0 :             const Block *b1 = mBlocks[i].get();
      60           0 :             const Block *b2 = aOther->mBlocks[i].get();
      61           0 :             if (!b1 != !b2) {
      62           0 :                 return false;
      63             :             }
      64           0 :             if (!b1) {
      65           0 :                 continue;
      66             :             }
      67           0 :             if (memcmp(&b1->mBits, &b2->mBits, BLOCK_SIZE) != 0) {
      68           0 :                 return false;
      69             :             }
      70             :         }
      71           0 :         return true;
      72             :     }
      73             : 
      74           0 :     bool test(uint32_t aIndex) const {
      75           0 :         NS_ASSERTION(mBlocks.DebugGetHeader(), "mHdr is null, this is bad");
      76           0 :         uint32_t blockIndex = aIndex/BLOCK_SIZE_BITS;
      77           0 :         if (blockIndex >= mBlocks.Length()) {
      78           0 :             return false;
      79             :         }
      80           0 :         const Block *block = mBlocks[blockIndex].get();
      81           0 :         if (!block) {
      82           0 :             return false;
      83             :         }
      84           0 :         return ((block->mBits[(aIndex>>3) & (BLOCK_SIZE - 1)]) & (1 << (aIndex & 0x7))) != 0;
      85             :     }
      86             : 
      87             :     // dump out contents of bitmap
      88             :     void Dump(const char* aPrefix, eGfxLog aWhichLog) const;
      89             : 
      90             :     bool TestRange(uint32_t aStart, uint32_t aEnd) {
      91             :         uint32_t startBlock, endBlock, blockLen;
      92             :         
      93             :         // start point is beyond the end of the block array? return false immediately
      94             :         startBlock = aStart >> BLOCK_INDEX_SHIFT;
      95             :         blockLen = mBlocks.Length();
      96             :         if (startBlock >= blockLen) return false;
      97             :         
      98             :         // check for blocks in range, if none, return false
      99             :         uint32_t blockIndex;
     100             :         bool hasBlocksInRange = false;
     101             : 
     102             :         endBlock = aEnd >> BLOCK_INDEX_SHIFT;
     103             :         for (blockIndex = startBlock; blockIndex <= endBlock; blockIndex++) {
     104             :             if (blockIndex < blockLen && mBlocks[blockIndex]) {
     105             :                 hasBlocksInRange = true;
     106             :             }
     107             :         }
     108             :         if (!hasBlocksInRange) {
     109             :             return false;
     110             :         }
     111             : 
     112             :         Block *block;
     113             :         uint32_t i, start, end;
     114             :         
     115             :         // first block, check bits
     116             :         if ((block = mBlocks[startBlock].get())) {
     117             :             start = aStart;
     118             :             end = std::min(aEnd, ((startBlock+1) << BLOCK_INDEX_SHIFT) - 1);
     119             :             for (i = start; i <= end; i++) {
     120             :                 if ((block->mBits[(i>>3) & (BLOCK_SIZE - 1)]) & (1 << (i & 0x7))) {
     121             :                     return true;
     122             :                 }
     123             :             }
     124             :         }
     125             :         if (endBlock == startBlock) {
     126             :             return false;
     127             :         }
     128             : 
     129             :         // [2..n-1] blocks check bytes
     130             :         for (blockIndex = startBlock + 1; blockIndex < endBlock; blockIndex++) {
     131             :             uint32_t index;
     132             :             
     133             :             if (blockIndex >= blockLen ||
     134             :                 !(block = mBlocks[blockIndex].get())) {
     135             :                 continue;
     136             :             }
     137             :             for (index = 0; index < BLOCK_SIZE; index++) {
     138             :                 if (block->mBits[index]) {
     139             :                     return true;
     140             :                 }
     141             :             }
     142             :         }
     143             :         
     144             :         // last block, check bits
     145             :         if (endBlock < blockLen && (block = mBlocks[endBlock].get())) {
     146             :             start = endBlock << BLOCK_INDEX_SHIFT;
     147             :             end = aEnd;
     148             :             for (i = start; i <= end; i++) {
     149             :                 if ((block->mBits[(i>>3) & (BLOCK_SIZE - 1)]) & (1 << (i & 0x7))) {
     150             :                     return true;
     151             :                 }
     152             :             }
     153             :         }
     154             :         
     155             :         return false;
     156             :     }
     157             :     
     158           0 :     void set(uint32_t aIndex) {
     159           0 :         uint32_t blockIndex = aIndex/BLOCK_SIZE_BITS;
     160           0 :         if (blockIndex >= mBlocks.Length()) {
     161           0 :             mBlocks.AppendElements(blockIndex + 1 - mBlocks.Length());
     162             :         }
     163           0 :         Block *block = mBlocks[blockIndex].get();
     164           0 :         if (!block) {
     165           0 :             block = new Block;
     166           0 :             mBlocks[blockIndex].reset(block);
     167             :         }
     168           0 :         block->mBits[(aIndex>>3) & (BLOCK_SIZE - 1)] |= 1 << (aIndex & 0x7);
     169           0 :     }
     170             : 
     171             :     void set(uint32_t aIndex, bool aValue) {
     172             :         if (aValue)
     173             :             set(aIndex);
     174             :         else
     175             :             clear(aIndex);
     176             :     }
     177             : 
     178           6 :     void SetRange(uint32_t aStart, uint32_t aEnd) {
     179           6 :         const uint32_t startIndex = aStart/BLOCK_SIZE_BITS;
     180           6 :         const uint32_t endIndex = aEnd/BLOCK_SIZE_BITS;
     181             : 
     182           6 :         if (endIndex >= mBlocks.Length()) {
     183           3 :             uint32_t numNewBlocks = endIndex + 1 - mBlocks.Length();
     184           3 :             mBlocks.AppendElements(numNewBlocks);
     185             :         }
     186             : 
     187          12 :         for (uint32_t i = startIndex; i <= endIndex; ++i) {
     188           6 :             const uint32_t blockFirstBit = i * BLOCK_SIZE_BITS;
     189           6 :             const uint32_t blockLastBit = blockFirstBit + BLOCK_SIZE_BITS - 1;
     190             : 
     191           6 :             Block *block = mBlocks[i].get();
     192           6 :             if (!block) {
     193             :                 bool fullBlock =
     194           3 :                     (aStart <= blockFirstBit && aEnd >= blockLastBit);
     195             : 
     196           3 :                 block = new Block(fullBlock ? 0xFF : 0);
     197           3 :                 mBlocks[i].reset(block);
     198             : 
     199           3 :                 if (fullBlock) {
     200           0 :                     continue;
     201             :                 }
     202             :             }
     203             : 
     204           6 :             const uint32_t start = aStart > blockFirstBit ? aStart - blockFirstBit : 0;
     205           6 :             const uint32_t end = std::min<uint32_t>(aEnd - blockFirstBit, BLOCK_SIZE_BITS - 1);
     206             : 
     207         201 :             for (uint32_t bit = start; bit <= end; ++bit) {
     208         195 :                 block->mBits[bit>>3] |= 1 << (bit & 0x7);
     209             :             }
     210             :         }
     211           6 :     }
     212             : 
     213             :     void clear(uint32_t aIndex) {
     214             :         uint32_t blockIndex = aIndex/BLOCK_SIZE_BITS;
     215             :         if (blockIndex >= mBlocks.Length()) {
     216             :             mBlocks.AppendElements(blockIndex + 1 - mBlocks.Length());
     217             :         }
     218             :         Block *block = mBlocks[blockIndex].get();
     219             :         if (!block) {
     220             :             return;
     221             :         }
     222             :         block->mBits[(aIndex>>3) & (BLOCK_SIZE - 1)] &= ~(1 << (aIndex & 0x7));
     223             :     }
     224             : 
     225             :     void ClearRange(uint32_t aStart, uint32_t aEnd) {
     226             :         const uint32_t startIndex = aStart/BLOCK_SIZE_BITS;
     227             :         const uint32_t endIndex = aEnd/BLOCK_SIZE_BITS;
     228             : 
     229             :         if (endIndex >= mBlocks.Length()) {
     230             :             uint32_t numNewBlocks = endIndex + 1 - mBlocks.Length();
     231             :             mBlocks.AppendElements(numNewBlocks);
     232             :         }
     233             : 
     234             :         for (uint32_t i = startIndex; i <= endIndex; ++i) {
     235             :             const uint32_t blockFirstBit = i * BLOCK_SIZE_BITS;
     236             : 
     237             :             Block *block = mBlocks[i].get();
     238             :             if (!block) {
     239             :                 // any nonexistent block is implicitly all clear,
     240             :                 // so there's no need to even create it
     241             :                 continue;
     242             :             }
     243             : 
     244             :             const uint32_t start = aStart > blockFirstBit ? aStart - blockFirstBit : 0;
     245             :             const uint32_t end = std::min<uint32_t>(aEnd - blockFirstBit, BLOCK_SIZE_BITS - 1);
     246             : 
     247             :             for (uint32_t bit = start; bit <= end; ++bit) {
     248             :                 block->mBits[bit>>3] &= ~(1 << (bit & 0x7));
     249             :             }
     250             :         }
     251             :     }
     252             : 
     253           0 :     size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
     254           0 :         size_t total = mBlocks.ShallowSizeOfExcludingThis(aMallocSizeOf);
     255           0 :         for (uint32_t i = 0; i < mBlocks.Length(); i++) {
     256           0 :             if (mBlocks[i]) {
     257           0 :                 total += aMallocSizeOf(mBlocks[i].get());
     258             :             }
     259             :         }
     260           0 :         return total;
     261             :     }
     262             : 
     263           0 :     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
     264           0 :         return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     265             :     }
     266             : 
     267             :     // clear out all blocks in the array
     268           3 :     void reset() {
     269             :         uint32_t i;
     270           3 :         for (i = 0; i < mBlocks.Length(); i++) {
     271           0 :             mBlocks[i] = nullptr;
     272             :         }
     273           3 :     }
     274             : 
     275             :     // set this bitset to the union of its current contents and another
     276           0 :     void Union(const gfxSparseBitSet& aBitset) {
     277             :         // ensure mBlocks is large enough
     278           0 :         uint32_t blockCount = aBitset.mBlocks.Length();
     279           0 :         if (blockCount > mBlocks.Length()) {
     280           0 :             uint32_t needed = blockCount - mBlocks.Length();
     281           0 :             mBlocks.AppendElements(needed);
     282             :         }
     283             :         // for each block that may be present in aBitset...
     284           0 :         for (uint32_t i = 0; i < blockCount; ++i) {
     285             :             // if it is missing (implicitly empty), just skip
     286           0 :             if (!aBitset.mBlocks[i]) {
     287           0 :                 continue;
     288             :             }
     289             :             // if the block is missing in this set, just copy the other
     290           0 :             if (!mBlocks[i]) {
     291           0 :                 mBlocks[i] = mozilla::MakeUnique<Block>(*aBitset.mBlocks[i]);
     292           0 :                 continue;
     293             :             }
     294             :             // else set existing block to the union of both
     295           0 :             uint32_t *dst = reinterpret_cast<uint32_t*>(mBlocks[i]->mBits);
     296             :             const uint32_t *src =
     297           0 :                 reinterpret_cast<const uint32_t*>(aBitset.mBlocks[i]->mBits);
     298           0 :             for (uint32_t j = 0; j < BLOCK_SIZE / 4; ++j) {
     299           0 :                 dst[j] |= src[j];
     300             :             }
     301             :         }
     302           0 :     }
     303             : 
     304           0 :     void Compact() {
     305           0 :         mBlocks.Compact();
     306           0 :     }
     307             : 
     308           0 :     uint32_t GetChecksum() const {
     309           0 :         uint32_t check = adler32(0, Z_NULL, 0);
     310           0 :         for (uint32_t i = 0; i < mBlocks.Length(); i++) {
     311           0 :             if (mBlocks[i]) {
     312           0 :                 const Block *block = mBlocks[i].get();
     313           0 :                 check = adler32(check, (uint8_t*) (&i), 4);
     314           0 :                 check = adler32(check, (uint8_t*) block, sizeof(Block));
     315             :             }
     316             :         }
     317           0 :         return check;
     318             :     }
     319             : 
     320             : private:
     321             :     nsTArray<mozilla::UniquePtr<Block>> mBlocks;
     322             : };
     323             : 
     324             : #define TRUETYPE_TAG(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
     325             : 
     326             : namespace mozilla {
     327             : 
     328             : // Byte-swapping types and name table structure definitions moved from
     329             : // gfxFontUtils.cpp to .h file so that gfxFont.cpp can also refer to them
     330             : #pragma pack(1)
     331             : 
     332             : struct AutoSwap_PRUint16 {
     333             : #ifdef __SUNPRO_CC
     334             :     AutoSwap_PRUint16& operator = (const uint16_t aValue)
     335             :     {
     336             :         this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
     337             :         return *this;
     338             :     }
     339             : #else
     340           0 :     MOZ_IMPLICIT AutoSwap_PRUint16(uint16_t aValue)
     341           0 :     {
     342           0 :         value = mozilla::NativeEndian::swapToBigEndian(aValue);
     343           0 :     }
     344             : #endif
     345           2 :     operator uint16_t() const
     346             :     {
     347           2 :         return mozilla::NativeEndian::swapFromBigEndian(value);
     348             :     }
     349             : 
     350           0 :     operator uint32_t() const
     351             :     {
     352           0 :         return mozilla::NativeEndian::swapFromBigEndian(value);
     353             :     }
     354             : 
     355           0 :     operator uint64_t() const
     356             :     {
     357           0 :         return mozilla::NativeEndian::swapFromBigEndian(value);
     358             :     }
     359             : 
     360             : private:
     361             :     uint16_t value;
     362             : };
     363             : 
     364             : struct AutoSwap_PRInt16 {
     365             : #ifdef __SUNPRO_CC
     366             :     AutoSwap_PRInt16& operator = (const int16_t aValue)
     367             :     {
     368             :         this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
     369             :         return *this;
     370             :     }
     371             : #else
     372             :     MOZ_IMPLICIT AutoSwap_PRInt16(int16_t aValue)
     373             :     {
     374             :         value = mozilla::NativeEndian::swapToBigEndian(aValue);
     375             :     }
     376             : #endif
     377           0 :     operator int16_t() const
     378             :     {
     379           0 :         return mozilla::NativeEndian::swapFromBigEndian(value);
     380             :     }
     381             : 
     382             :     operator uint32_t() const
     383             :     {
     384             :         return mozilla::NativeEndian::swapFromBigEndian(value);
     385             :     }
     386             : 
     387             : private:
     388             :     int16_t  value;
     389             : };
     390             : 
     391             : struct AutoSwap_PRUint32 {
     392             : #ifdef __SUNPRO_CC
     393             :     AutoSwap_PRUint32& operator = (const uint32_t aValue)
     394             :     {
     395             :         this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
     396             :         return *this;
     397             :     }
     398             : #else
     399           0 :     MOZ_IMPLICIT AutoSwap_PRUint32(uint32_t aValue)
     400           0 :     {
     401           0 :         value = mozilla::NativeEndian::swapToBigEndian(aValue);
     402           0 :     }
     403             : #endif
     404           0 :     operator uint32_t() const
     405             :     {
     406           0 :         return mozilla::NativeEndian::swapFromBigEndian(value);
     407             :     }
     408             : 
     409             : private:
     410             :     uint32_t  value;
     411             : };
     412             : 
     413             : struct AutoSwap_PRInt32 {
     414             : #ifdef __SUNPRO_CC
     415             :     AutoSwap_PRInt32& operator = (const int32_t aValue)
     416             :     {
     417             :         this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
     418             :         return *this;
     419             :     }
     420             : #else
     421             :     MOZ_IMPLICIT AutoSwap_PRInt32(int32_t aValue)
     422             :     {
     423             :         value = mozilla::NativeEndian::swapToBigEndian(aValue);
     424             :     }
     425             : #endif
     426             :     operator int32_t() const
     427             :     {
     428             :         return mozilla::NativeEndian::swapFromBigEndian(value);
     429             :     }
     430             : 
     431             : private:
     432             :     int32_t  value;
     433             : };
     434             : 
     435             : struct AutoSwap_PRUint64 {
     436             : #ifdef __SUNPRO_CC
     437             :     AutoSwap_PRUint64& operator = (const uint64_t aValue)
     438             :     {
     439             :         this->value = mozilla::NativeEndian::swapToBigEndian(aValue);
     440             :         return *this;
     441             :     }
     442             : #else
     443             :     MOZ_IMPLICIT AutoSwap_PRUint64(uint64_t aValue)
     444             :     {
     445             :         value = mozilla::NativeEndian::swapToBigEndian(aValue);
     446             :     }
     447             : #endif
     448             :     operator uint64_t() const
     449             :     {
     450             :         return mozilla::NativeEndian::swapFromBigEndian(value);
     451             :     }
     452             : 
     453             : private:
     454             :     uint64_t  value;
     455             : };
     456             : 
     457             : struct AutoSwap_PRUint24 {
     458           0 :     operator uint32_t() const { return value[0] << 16 | value[1] << 8 | value[2]; }
     459             : private:
     460             :     AutoSwap_PRUint24() { }
     461             :     uint8_t  value[3];
     462             : };
     463             : 
     464             : struct SFNTHeader {
     465             :     AutoSwap_PRUint32    sfntVersion;            // Fixed, 0x00010000 for version 1.0.
     466             :     AutoSwap_PRUint16    numTables;              // Number of tables.
     467             :     AutoSwap_PRUint16    searchRange;            // (Maximum power of 2 <= numTables) x 16.
     468             :     AutoSwap_PRUint16    entrySelector;          // Log2(maximum power of 2 <= numTables).
     469             :     AutoSwap_PRUint16    rangeShift;             // NumTables x 16-searchRange.        
     470             : };
     471             : 
     472             : struct TableDirEntry {
     473             :     AutoSwap_PRUint32    tag;                    // 4 -byte identifier.
     474             :     AutoSwap_PRUint32    checkSum;               // CheckSum for this table.
     475             :     AutoSwap_PRUint32    offset;                 // Offset from beginning of TrueType font file.
     476             :     AutoSwap_PRUint32    length;                 // Length of this table.        
     477             : };
     478             : 
     479             : struct HeadTable {
     480             :     enum {
     481             :         HEAD_VERSION = 0x00010000,
     482             :         HEAD_MAGIC_NUMBER = 0x5F0F3CF5,
     483             :         HEAD_CHECKSUM_CALC_CONST = 0xB1B0AFBA
     484             :     };
     485             : 
     486             :     AutoSwap_PRUint32    tableVersionNumber;    // Fixed, 0x00010000 for version 1.0.
     487             :     AutoSwap_PRUint32    fontRevision;          // Set by font manufacturer.
     488             :     AutoSwap_PRUint32    checkSumAdjustment;    // To compute: set it to 0, sum the entire font as ULONG, then store 0xB1B0AFBA - sum.
     489             :     AutoSwap_PRUint32    magicNumber;           // Set to 0x5F0F3CF5.
     490             :     AutoSwap_PRUint16    flags;
     491             :     AutoSwap_PRUint16    unitsPerEm;            // Valid range is from 16 to 16384. This value should be a power of 2 for fonts that have TrueType outlines.
     492             :     AutoSwap_PRUint64    created;               // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
     493             :     AutoSwap_PRUint64    modified;              // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
     494             :     AutoSwap_PRInt16     xMin;                  // For all glyph bounding boxes.
     495             :     AutoSwap_PRInt16     yMin;                  // For all glyph bounding boxes.
     496             :     AutoSwap_PRInt16     xMax;                  // For all glyph bounding boxes.
     497             :     AutoSwap_PRInt16     yMax;                  // For all glyph bounding boxes.
     498             :     AutoSwap_PRUint16    macStyle;              // Bit 0: Bold (if set to 1);
     499             :     AutoSwap_PRUint16    lowestRecPPEM;         // Smallest readable size in pixels.
     500             :     AutoSwap_PRInt16     fontDirectionHint;
     501             :     AutoSwap_PRInt16     indexToLocFormat;
     502             :     AutoSwap_PRInt16     glyphDataFormat;
     503             : };
     504             : 
     505             : struct OS2Table {
     506             :     AutoSwap_PRUint16    version;                // 0004 = OpenType 1.5
     507             :     AutoSwap_PRInt16     xAvgCharWidth;
     508             :     AutoSwap_PRUint16    usWeightClass;
     509             :     AutoSwap_PRUint16    usWidthClass;
     510             :     AutoSwap_PRUint16    fsType;
     511             :     AutoSwap_PRInt16     ySubscriptXSize;
     512             :     AutoSwap_PRInt16     ySubscriptYSize;
     513             :     AutoSwap_PRInt16     ySubscriptXOffset;
     514             :     AutoSwap_PRInt16     ySubscriptYOffset;
     515             :     AutoSwap_PRInt16     ySuperscriptXSize;
     516             :     AutoSwap_PRInt16     ySuperscriptYSize;
     517             :     AutoSwap_PRInt16     ySuperscriptXOffset;
     518             :     AutoSwap_PRInt16     ySuperscriptYOffset;
     519             :     AutoSwap_PRInt16     yStrikeoutSize;
     520             :     AutoSwap_PRInt16     yStrikeoutPosition;
     521             :     AutoSwap_PRInt16     sFamilyClass;
     522             :     uint8_t              panose[10];
     523             :     AutoSwap_PRUint32    unicodeRange1;
     524             :     AutoSwap_PRUint32    unicodeRange2;
     525             :     AutoSwap_PRUint32    unicodeRange3;
     526             :     AutoSwap_PRUint32    unicodeRange4;
     527             :     uint8_t              achVendID[4];
     528             :     AutoSwap_PRUint16    fsSelection;
     529             :     AutoSwap_PRUint16    usFirstCharIndex;
     530             :     AutoSwap_PRUint16    usLastCharIndex;
     531             :     AutoSwap_PRInt16     sTypoAscender;
     532             :     AutoSwap_PRInt16     sTypoDescender;
     533             :     AutoSwap_PRInt16     sTypoLineGap;
     534             :     AutoSwap_PRUint16    usWinAscent;
     535             :     AutoSwap_PRUint16    usWinDescent;
     536             :     AutoSwap_PRUint32    codePageRange1;
     537             :     AutoSwap_PRUint32    codePageRange2;
     538             :     AutoSwap_PRInt16     sxHeight;
     539             :     AutoSwap_PRInt16     sCapHeight;
     540             :     AutoSwap_PRUint16    usDefaultChar;
     541             :     AutoSwap_PRUint16    usBreakChar;
     542             :     AutoSwap_PRUint16    usMaxContext;
     543             : };
     544             : 
     545             : struct PostTable {
     546             :     AutoSwap_PRUint32    version;
     547             :     AutoSwap_PRInt32     italicAngle;
     548             :     AutoSwap_PRInt16     underlinePosition;
     549             :     AutoSwap_PRUint16    underlineThickness;
     550             :     AutoSwap_PRUint32    isFixedPitch;
     551             :     AutoSwap_PRUint32    minMemType42;
     552             :     AutoSwap_PRUint32    maxMemType42;
     553             :     AutoSwap_PRUint32    minMemType1;
     554             :     AutoSwap_PRUint32    maxMemType1;
     555             : };
     556             : 
     557             : // This structure is used for both 'hhea' and 'vhea' tables.
     558             : // The field names here are those of the horizontal version; the
     559             : // vertical table just exchanges vertical and horizontal coordinates.
     560             : struct MetricsHeader {
     561             :     AutoSwap_PRUint32    version;
     562             :     AutoSwap_PRInt16     ascender;
     563             :     AutoSwap_PRInt16     descender;
     564             :     AutoSwap_PRInt16     lineGap;
     565             :     AutoSwap_PRUint16    advanceWidthMax;
     566             :     AutoSwap_PRInt16     minLeftSideBearing;
     567             :     AutoSwap_PRInt16     minRightSideBearing;
     568             :     AutoSwap_PRInt16     xMaxExtent;
     569             :     AutoSwap_PRInt16     caretSlopeRise;
     570             :     AutoSwap_PRInt16     caretSlopeRun;
     571             :     AutoSwap_PRInt16     caretOffset;
     572             :     AutoSwap_PRInt16     reserved1;
     573             :     AutoSwap_PRInt16     reserved2;
     574             :     AutoSwap_PRInt16     reserved3;
     575             :     AutoSwap_PRInt16     reserved4;
     576             :     AutoSwap_PRInt16     metricDataFormat;
     577             :     AutoSwap_PRUint16    numOfLongMetrics;
     578             : };
     579             : 
     580             : struct MaxpTableHeader {
     581             :     AutoSwap_PRUint32    version; // CFF: 0x00005000; TrueType: 0x00010000
     582             :     AutoSwap_PRUint16    numGlyphs;
     583             : // truetype version has additional fields that we don't currently use
     584             : };
     585             : 
     586             : // old 'kern' table, supported on Windows
     587             : // see http://www.microsoft.com/typography/otspec/kern.htm
     588             : struct KernTableVersion0 {
     589             :     AutoSwap_PRUint16    version; // 0x0000
     590             :     AutoSwap_PRUint16    nTables;
     591             : };
     592             : 
     593             : struct KernTableSubtableHeaderVersion0 {
     594             :     AutoSwap_PRUint16    version;
     595             :     AutoSwap_PRUint16    length;
     596             :     AutoSwap_PRUint16    coverage;
     597             : };
     598             : 
     599             : // newer Mac-only 'kern' table, ignored by Windows
     600             : // see http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6kern.html
     601             : struct KernTableVersion1 {
     602             :     AutoSwap_PRUint32    version; // 0x00010000
     603             :     AutoSwap_PRUint32    nTables;
     604             : };
     605             : 
     606             : struct KernTableSubtableHeaderVersion1 {
     607             :     AutoSwap_PRUint32    length;
     608             :     AutoSwap_PRUint16    coverage;
     609             :     AutoSwap_PRUint16    tupleIndex;
     610             : };
     611             : 
     612             : struct COLRHeader {
     613             :     AutoSwap_PRUint16    version;
     614             :     AutoSwap_PRUint16    numBaseGlyphRecord;
     615             :     AutoSwap_PRUint32    offsetBaseGlyphRecord;
     616             :     AutoSwap_PRUint32    offsetLayerRecord;
     617             :     AutoSwap_PRUint16    numLayerRecords;
     618             : };
     619             : 
     620             : struct CPALHeaderVersion0 {
     621             :     AutoSwap_PRUint16    version;
     622             :     AutoSwap_PRUint16    numPaletteEntries;
     623             :     AutoSwap_PRUint16    numPalettes;
     624             :     AutoSwap_PRUint16    numColorRecords;
     625             :     AutoSwap_PRUint32    offsetFirstColorRecord;
     626             : };
     627             : 
     628             : #pragma pack()
     629             : 
     630             : // Return just the highest bit of the given value, i.e., the highest
     631             : // power of 2 that is <= value, or zero if the input value is zero.
     632             : inline uint32_t
     633           0 : FindHighestBit(uint32_t value)
     634             : {
     635             :     // propagate highest bit into all lower bits of the value
     636           0 :     value |= (value >> 1);
     637           0 :     value |= (value >> 2);
     638           0 :     value |= (value >> 4);
     639           0 :     value |= (value >> 8);
     640           0 :     value |= (value >> 16);
     641             :     // isolate the leftmost bit
     642           0 :     return (value & ~(value >> 1));
     643             : }
     644             : 
     645             : } // namespace mozilla
     646             : 
     647             : // used for overlaying name changes without touching original font data
     648             : struct FontDataOverlay {
     649             :     // overlaySrc != 0 ==> use overlay
     650             :     uint32_t  overlaySrc;    // src offset from start of font data
     651             :     uint32_t  overlaySrcLen; // src length
     652             :     uint32_t  overlayDest;   // dest offset from start of font data
     653             : };
     654             :     
     655             : enum gfxUserFontType {
     656             :     GFX_USERFONT_UNKNOWN = 0,
     657             :     GFX_USERFONT_OPENTYPE = 1,
     658             :     GFX_USERFONT_SVG = 2,
     659             :     GFX_USERFONT_WOFF = 3,
     660             :     GFX_USERFONT_WOFF2 = 4
     661             : };
     662             : #define GFX_PREF_WOFF2_ENABLED "gfx.downloadable_fonts.woff2.enabled"
     663             : 
     664             : extern const uint8_t sCJKCompatSVSTable[];
     665             : 
     666             : class gfxFontUtils {
     667             : 
     668             : public:
     669             :     // these are public because gfxFont.cpp also looks into the name table
     670             :     enum {
     671             :         NAME_ID_FAMILY = 1,
     672             :         NAME_ID_STYLE = 2,
     673             :         NAME_ID_UNIQUE = 3,
     674             :         NAME_ID_FULL = 4,
     675             :         NAME_ID_VERSION = 5,
     676             :         NAME_ID_POSTSCRIPT = 6,
     677             :         NAME_ID_PREFERRED_FAMILY = 16,
     678             :         NAME_ID_PREFERRED_STYLE = 17,
     679             : 
     680             :         PLATFORM_ALL = -1,
     681             :         PLATFORM_ID_UNICODE = 0,           // Mac OS uses this typically
     682             :         PLATFORM_ID_MAC = 1,
     683             :         PLATFORM_ID_ISO = 2,
     684             :         PLATFORM_ID_MICROSOFT = 3,
     685             : 
     686             :         ENCODING_ID_MAC_ROMAN = 0,         // traditional Mac OS script manager encodings
     687             :         ENCODING_ID_MAC_JAPANESE = 1,      // (there are others defined, but some were never
     688             :         ENCODING_ID_MAC_TRAD_CHINESE = 2,  // implemented by Apple, and I have never seen them
     689             :         ENCODING_ID_MAC_KOREAN = 3,        // used in font names)
     690             :         ENCODING_ID_MAC_ARABIC = 4,
     691             :         ENCODING_ID_MAC_HEBREW = 5,
     692             :         ENCODING_ID_MAC_GREEK = 6,
     693             :         ENCODING_ID_MAC_CYRILLIC = 7,
     694             :         ENCODING_ID_MAC_DEVANAGARI = 9,
     695             :         ENCODING_ID_MAC_GURMUKHI = 10,
     696             :         ENCODING_ID_MAC_GUJARATI = 11,
     697             :         ENCODING_ID_MAC_SIMP_CHINESE = 25,
     698             : 
     699             :         ENCODING_ID_MICROSOFT_SYMBOL = 0,  // Microsoft platform encoding IDs
     700             :         ENCODING_ID_MICROSOFT_UNICODEBMP = 1,
     701             :         ENCODING_ID_MICROSOFT_SHIFTJIS = 2,
     702             :         ENCODING_ID_MICROSOFT_PRC = 3,
     703             :         ENCODING_ID_MICROSOFT_BIG5 = 4,
     704             :         ENCODING_ID_MICROSOFT_WANSUNG = 5,
     705             :         ENCODING_ID_MICROSOFT_JOHAB  = 6,
     706             :         ENCODING_ID_MICROSOFT_UNICODEFULL = 10,
     707             : 
     708             :         LANG_ALL = -1,
     709             :         LANG_ID_MAC_ENGLISH = 0,      // many others are defined, but most don't affect
     710             :         LANG_ID_MAC_HEBREW = 10,      // the charset; should check all the central/eastern
     711             :         LANG_ID_MAC_JAPANESE = 11,    // european codes, though
     712             :         LANG_ID_MAC_ARABIC = 12,
     713             :         LANG_ID_MAC_ICELANDIC = 15,
     714             :         LANG_ID_MAC_TURKISH = 17,
     715             :         LANG_ID_MAC_TRAD_CHINESE = 19,
     716             :         LANG_ID_MAC_URDU = 20,
     717             :         LANG_ID_MAC_KOREAN = 23,
     718             :         LANG_ID_MAC_POLISH = 25,
     719             :         LANG_ID_MAC_FARSI = 31,
     720             :         LANG_ID_MAC_SIMP_CHINESE = 33,
     721             :         LANG_ID_MAC_ROMANIAN = 37,
     722             :         LANG_ID_MAC_CZECH = 38,
     723             :         LANG_ID_MAC_SLOVAK = 39,
     724             : 
     725             :         LANG_ID_MICROSOFT_EN_US = 0x0409,        // with Microsoft platformID, EN US lang code
     726             :         
     727             :         CMAP_MAX_CODEPOINT = 0x10ffff     // maximum possible Unicode codepoint 
     728             :                                           // contained in a cmap
     729             :     };
     730             : 
     731             :     // name table has a header, followed by name records, followed by string data
     732             :     struct NameHeader {
     733             :         mozilla::AutoSwap_PRUint16    format;       // Format selector (=0).
     734             :         mozilla::AutoSwap_PRUint16    count;        // Number of name records.
     735             :         mozilla::AutoSwap_PRUint16    stringOffset; // Offset to start of string storage
     736             :                                                     // (from start of table)
     737             :     };
     738             : 
     739             :     struct NameRecord {
     740             :         mozilla::AutoSwap_PRUint16    platformID;   // Platform ID
     741             :         mozilla::AutoSwap_PRUint16    encodingID;   // Platform-specific encoding ID
     742             :         mozilla::AutoSwap_PRUint16    languageID;   // Language ID
     743             :         mozilla::AutoSwap_PRUint16    nameID;       // Name ID.
     744             :         mozilla::AutoSwap_PRUint16    length;       // String length (in bytes).
     745             :         mozilla::AutoSwap_PRUint16    offset;       // String offset from start of storage
     746             :                                                     // (in bytes).
     747             :     };
     748             : 
     749             :     // for reading big-endian font data on either big or little-endian platforms
     750             : 
     751             :     static inline uint16_t
     752           0 :     ReadShortAt(const uint8_t *aBuf, uint32_t aIndex)
     753             :     {
     754           0 :         return (aBuf[aIndex] << 8) | aBuf[aIndex + 1];
     755             :     }
     756             : 
     757             :     static inline uint16_t
     758           0 :     ReadShortAt16(const uint16_t *aBuf, uint32_t aIndex)
     759             :     {
     760           0 :         const uint8_t *buf = reinterpret_cast<const uint8_t*>(aBuf);
     761           0 :         uint32_t index = aIndex << 1;
     762           0 :         return (buf[index] << 8) | buf[index+1];
     763             :     }
     764             : 
     765             :     static inline uint32_t
     766           0 :     ReadUint24At(const uint8_t *aBuf, uint32_t aIndex)
     767             :     {
     768           0 :         return ((aBuf[aIndex] << 16) | (aBuf[aIndex + 1] << 8) |
     769           0 :                 (aBuf[aIndex + 2]));
     770             :     }
     771             : 
     772             :     static inline uint32_t
     773           0 :     ReadLongAt(const uint8_t *aBuf, uint32_t aIndex)
     774             :     {
     775           0 :         return ((aBuf[aIndex] << 24) | (aBuf[aIndex + 1] << 16) | 
     776           0 :                 (aBuf[aIndex + 2] << 8) | (aBuf[aIndex + 3]));
     777             :     }
     778             : 
     779             :     static nsresult
     780             :     ReadCMAPTableFormat10(const uint8_t *aBuf, uint32_t aLength,
     781             :                           gfxSparseBitSet& aCharacterMap);
     782             : 
     783             :     static nsresult
     784             :     ReadCMAPTableFormat12or13(const uint8_t *aBuf, uint32_t aLength, 
     785             :                               gfxSparseBitSet& aCharacterMap);
     786             : 
     787             :     static nsresult 
     788             :     ReadCMAPTableFormat4(const uint8_t *aBuf, uint32_t aLength, 
     789             :                          gfxSparseBitSet& aCharacterMap);
     790             : 
     791             :     static nsresult
     792             :     ReadCMAPTableFormat14(const uint8_t *aBuf, uint32_t aLength, 
     793             :                           mozilla::UniquePtr<uint8_t[]>& aTable);
     794             : 
     795             :     static uint32_t
     796             :     FindPreferredSubtable(const uint8_t *aBuf, uint32_t aBufLength,
     797             :                           uint32_t *aTableOffset, uint32_t *aUVSTableOffset,
     798             :                           bool *aSymbolEncoding);
     799             : 
     800             :     static nsresult
     801             :     ReadCMAP(const uint8_t *aBuf, uint32_t aBufLength,
     802             :              gfxSparseBitSet& aCharacterMap,
     803             :              uint32_t& aUVSOffset,
     804             :              bool& aUnicodeFont, bool& aSymbolFont);
     805             : 
     806             :     static uint32_t
     807             :     MapCharToGlyphFormat4(const uint8_t *aBuf, char16_t aCh);
     808             : 
     809             :     static uint32_t
     810             :     MapCharToGlyphFormat10(const uint8_t *aBuf, uint32_t aCh);
     811             : 
     812             :     static uint32_t
     813             :     MapCharToGlyphFormat12or13(const uint8_t *aBuf, uint32_t aCh);
     814             : 
     815             :     static uint16_t
     816             :     MapUVSToGlyphFormat14(const uint8_t *aBuf, uint32_t aCh, uint32_t aVS);
     817             : 
     818             :     // sCJKCompatSVSTable is a 'cmap' format 14 subtable that maps
     819             :     // <char + var-selector> pairs to the corresponding Unicode
     820             :     // compatibility ideograph codepoints.
     821             :     static MOZ_ALWAYS_INLINE uint32_t
     822           0 :     GetUVSFallback(uint32_t aCh, uint32_t aVS) {
     823           0 :         aCh = MapUVSToGlyphFormat14(sCJKCompatSVSTable, aCh, aVS);
     824           0 :         return aCh >= 0xFB00 ? aCh + (0x2F800 - 0xFB00) : aCh;
     825             :     }
     826             : 
     827             :     static uint32_t
     828             :     MapCharToGlyph(const uint8_t *aCmapBuf, uint32_t aBufLength,
     829             :                    uint32_t aUnicode, uint32_t aVarSelector = 0);
     830             : 
     831             : #ifdef XP_WIN
     832             :     // determine whether a font (which has already been sanitized, so is known
     833             :     // to be a valid sfnt) is CFF format rather than TrueType
     834             :     static bool
     835             :     IsCffFont(const uint8_t* aFontData);
     836             : #endif
     837             : 
     838             :     // determine the format of font data
     839             :     static gfxUserFontType
     840             :     DetermineFontDataType(const uint8_t *aFontData, uint32_t aFontDataLength);
     841             : 
     842             :     // Read the fullname from the sfnt data (used to save the original name
     843             :     // prior to renaming the font for installation).
     844             :     // This is called with sfnt data that has already been validated,
     845             :     // so it should always succeed in finding the name table.
     846             :     static nsresult
     847             :     GetFullNameFromSFNT(const uint8_t* aFontData, uint32_t aLength,
     848             :                         nsAString& aFullName);
     849             : 
     850             :     // helper to get fullname from name table, constructing from family+style
     851             :     // if no explicit fullname is present
     852             :     static nsresult
     853             :     GetFullNameFromTable(hb_blob_t *aNameTable,
     854             :                          nsAString& aFullName);
     855             : 
     856             :     // helper to get family name from name table
     857             :     static nsresult
     858             :     GetFamilyNameFromTable(hb_blob_t *aNameTable,
     859             :                            nsAString& aFamilyName);
     860             : 
     861             :     // Find the table directory entry for a given table tag, in a (validated)
     862             :     // buffer of 'sfnt' data. Returns null if the tag is not present.
     863             :     static mozilla::TableDirEntry*
     864             :     FindTableDirEntry(const void* aFontData, uint32_t aTableTag);
     865             : 
     866             :     // Return a blob that wraps a table found within a buffer of font data.
     867             :     // The blob does NOT own its data; caller guarantees that the buffer
     868             :     // will remain valid at least as long as the blob.
     869             :     // Returns null if the specified table is not found.
     870             :     // This method assumes aFontData is valid 'sfnt' data; before using this,
     871             :     // caller is responsible to do any sanitization/validation necessary.
     872             :     static hb_blob_t*
     873             :     GetTableFromFontData(const void* aFontData, uint32_t aTableTag);
     874             : 
     875             :     // create a new name table and build a new font with that name table
     876             :     // appended on the end, returns true on success
     877             :     static nsresult
     878             :     RenameFont(const nsAString& aName, const uint8_t *aFontData, 
     879             :                uint32_t aFontDataLength, FallibleTArray<uint8_t> *aNewFont);
     880             :     
     881             :     // read all names matching aNameID, returning in aNames array
     882             :     static nsresult
     883             :     ReadNames(const char *aNameData, uint32_t aDataLen, uint32_t aNameID,
     884             :               int32_t aPlatformID, nsTArray<nsString>& aNames);
     885             : 
     886             :     // reads English or first name matching aNameID, returning in aName
     887             :     // platform based on OS
     888             :     static nsresult
     889             :     ReadCanonicalName(hb_blob_t *aNameTable, uint32_t aNameID,
     890             :                       nsString& aName);
     891             : 
     892             :     static nsresult
     893             :     ReadCanonicalName(const char *aNameData, uint32_t aDataLen,
     894             :                       uint32_t aNameID, nsString& aName);
     895             : 
     896             :     // convert a name from the raw name table data into an nsString,
     897             :     // provided we know how; return true if successful, or false
     898             :     // if we can't handle the encoding
     899             :     static bool
     900             :     DecodeFontName(const char *aBuf, int32_t aLength, 
     901             :                    uint32_t aPlatformCode, uint32_t aScriptCode,
     902             :                    uint32_t aLangCode, nsAString& dest);
     903             : 
     904         658 :     static inline bool IsJoinCauser(uint32_t ch) {
     905         658 :         return (ch == 0x200D);
     906             :     }
     907             : 
     908         658 :     static inline bool IsJoinControl(uint32_t ch) {
     909         658 :         return (ch == 0x200C || ch == 0x200D);
     910             :     }
     911             : 
     912             :     enum {
     913             :         kUnicodeVS1 = 0xFE00,
     914             :         kUnicodeVS16 = 0xFE0F,
     915             :         kUnicodeVS17 = 0xE0100,
     916             :         kUnicodeVS256 = 0xE01EF
     917             :     };
     918             : 
     919         658 :     static inline bool IsVarSelector(uint32_t ch) {
     920         658 :         return (ch >= kUnicodeVS1 && ch <= kUnicodeVS16) ||
     921         658 :                (ch >= kUnicodeVS17 && ch <= kUnicodeVS256);
     922             :     }
     923             : 
     924             :     enum {
     925             :         kUnicodeRegionalIndicatorA = 0x1F1E6,
     926             :         kUnicodeRegionalIndicatorZ = 0x1F1FF
     927             :     };
     928             : 
     929           0 :     static inline bool IsRegionalIndicator(uint32_t aCh) {
     930           0 :         return aCh >= kUnicodeRegionalIndicatorA &&
     931           0 :                aCh <= kUnicodeRegionalIndicatorZ;
     932             :     }
     933             : 
     934             :     static inline bool IsInvalid(uint32_t ch) {
     935             :         return (ch == 0xFFFD);
     936             :     }
     937             : 
     938             :     // Font code may want to know if there is the potential for bidi behavior
     939             :     // to be triggered by any of the characters in a text run; this can be
     940             :     // used to test that possibility.
     941             :     enum {
     942             :         kUnicodeBidiScriptsStart = 0x0590,
     943             :         kUnicodeBidiScriptsEnd = 0x08FF,
     944             :         kUnicodeBidiPresentationStart = 0xFB1D,
     945             :         kUnicodeBidiPresentationEnd = 0xFEFC,
     946             :         kUnicodeFirstHighSurrogateBlock = 0xD800,
     947             :         kUnicodeRLM = 0x200F,
     948             :         kUnicodeRLE = 0x202B,
     949             :         kUnicodeRLO = 0x202E
     950             :     };
     951             : 
     952             :     static inline bool PotentialRTLChar(char16_t aCh) {
     953             :         if (aCh >= kUnicodeBidiScriptsStart && aCh <= kUnicodeBidiScriptsEnd)
     954             :             // bidi scripts Hebrew, Arabic, Syriac, Thaana, N'Ko are all encoded together
     955             :             return true;
     956             : 
     957             :         if (aCh == kUnicodeRLM || aCh == kUnicodeRLE || aCh == kUnicodeRLO)
     958             :             // directional controls that trigger bidi layout
     959             :             return true;
     960             : 
     961             :         if (aCh >= kUnicodeBidiPresentationStart &&
     962             :             aCh <= kUnicodeBidiPresentationEnd)
     963             :             // presentation forms of Arabic and Hebrew letters
     964             :             return true;
     965             : 
     966             :         if ((aCh & 0xFF00) == kUnicodeFirstHighSurrogateBlock)
     967             :             // surrogate that could be part of a bidi supplementary char
     968             :             // (Cypriot, Aramaic, Phoenecian, etc)
     969             :             return true;
     970             : 
     971             :         // otherwise we know this char cannot trigger bidi reordering
     972             :         return false;
     973             :     }
     974             : 
     975             :     // parse a simple list of font family names into
     976             :     // an array of strings
     977             :     static void ParseFontList(const nsAString& aFamilyList,
     978             :                               nsTArray<nsString>& aFontList);
     979             : 
     980             :     // for a given font list pref name, append list of font names
     981             :     static void AppendPrefsFontList(const char *aPrefName,
     982             :                                     nsTArray<nsString>& aFontList);
     983             : 
     984             :     // for a given font list pref name, initialize a list of font names
     985             :     static void GetPrefsFontList(const char *aPrefName, 
     986             :                                  nsTArray<nsString>& aFontList);
     987             : 
     988             :     // generate a unique font name
     989             :     static nsresult MakeUniqueUserFontName(nsAString& aName);
     990             : 
     991             :     // for color layer from glyph using COLR and CPAL tables
     992             :     static bool ValidateColorGlyphs(hb_blob_t* aCOLR, hb_blob_t* aCPAL);
     993             :     static bool GetColorGlyphLayers(hb_blob_t* aCOLR,
     994             :                                     hb_blob_t* aCPAL,
     995             :                                     uint32_t aGlyphId,
     996             :                                     const mozilla::gfx::Color& aDefaultColor,
     997             :                                     nsTArray<uint16_t> &aGlyphs,
     998             :                                     nsTArray<mozilla::gfx::Color> &aColors);
     999             : 
    1000             : protected:
    1001             :     friend struct MacCharsetMappingComparator;
    1002             : 
    1003             :     static nsresult
    1004             :     ReadNames(const char *aNameData, uint32_t aDataLen, uint32_t aNameID,
    1005             :               int32_t aLangID, int32_t aPlatformID, nsTArray<nsString>& aNames);
    1006             : 
    1007             :     // convert opentype name-table platform/encoding/language values to a charset name
    1008             :     // we can use to convert the name data to unicode, or "" if data is UTF16BE
    1009             :     static const char*
    1010             :     GetCharsetForFontName(uint16_t aPlatform, uint16_t aScript, uint16_t aLanguage);
    1011             : 
    1012             :     struct MacFontNameCharsetMapping {
    1013             :         uint16_t    mEncoding;
    1014             :         uint16_t    mLanguage;
    1015             :         const char *mCharsetName;
    1016             : 
    1017           0 :         bool operator<(const MacFontNameCharsetMapping& rhs) const {
    1018           0 :             return (mEncoding < rhs.mEncoding) ||
    1019           0 :                    ((mEncoding == rhs.mEncoding) && (mLanguage < rhs.mLanguage));
    1020             :         }
    1021             :     };
    1022             :     static const MacFontNameCharsetMapping gMacFontNameCharsets[];
    1023             :     static const char* gISOFontNameCharsets[];
    1024             :     static const char* gMSFontNameCharsets[];
    1025             : };
    1026             : 
    1027             : #endif /* GFX_FONT_UTILS_H */

Generated by: LCOV version 1.13