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/. */
6 #ifndef GFX_FONT_UTILS_H
7 #define GFX_FONT_UTILS_H
9 #include "gfxPlatform.h"
10 #include "nsComponentManagerUtils.h"
12 #include "nsAutoPtr.h"
13 #include "mozilla/Likely.h"
14 #include "mozilla/Endian.h"
15 #include "mozilla/MemoryReporting.h"
20 /* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
26 typedef struct hb_blob_t hb_blob_t
;
28 class gfxSparseBitSet
{
30 enum { BLOCK_SIZE
= 32 }; // ==> 256 codepoints per block
31 enum { BLOCK_SIZE_BITS
= BLOCK_SIZE
* 8 };
32 enum { BLOCK_INDEX_SHIFT
= 8 };
35 Block(const Block
& aBlock
) { memcpy(mBits
, aBlock
.mBits
, sizeof(mBits
)); }
36 explicit Block(unsigned char memsetValue
= 0) { memset(mBits
, memsetValue
, BLOCK_SIZE
); }
37 uint8_t mBits
[BLOCK_SIZE
];
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
];
48 mBlocks
[i
] = new Block(*block
);
52 bool Equals(const gfxSparseBitSet
*aOther
) const {
53 if (mBlocks
.Length() != aOther
->mBlocks
.Length()) {
56 size_t n
= mBlocks
.Length();
57 for (size_t i
= 0; i
< n
; ++i
) {
58 const Block
*b1
= mBlocks
[i
];
59 const Block
*b2
= aOther
->mBlocks
[i
];
66 if (memcmp(&b1
->mBits
, &b2
->mBits
, BLOCK_SIZE
) != 0) {
73 bool test(uint32_t aIndex
) const {
74 NS_ASSERTION(mBlocks
.DebugGetHeader(), "mHdr is null, this is bad");
75 uint32_t blockIndex
= aIndex
/BLOCK_SIZE_BITS
;
76 if (blockIndex
>= mBlocks
.Length())
78 Block
*block
= mBlocks
[blockIndex
];
81 return ((block
->mBits
[(aIndex
>>3) & (BLOCK_SIZE
- 1)]) & (1 << (aIndex
& 0x7))) != 0;
85 // dump out contents of bitmap
86 void Dump(const char* aPrefix
, eGfxLog aWhichLog
) const;
89 bool TestRange(uint32_t aStart
, uint32_t aEnd
) {
90 uint32_t startBlock
, endBlock
, blockLen
;
92 // start point is beyond the end of the block array? return false immediately
93 startBlock
= aStart
>> BLOCK_INDEX_SHIFT
;
94 blockLen
= mBlocks
.Length();
95 if (startBlock
>= blockLen
) return false;
97 // check for blocks in range, if none, return false
99 bool hasBlocksInRange
= false;
101 endBlock
= aEnd
>> BLOCK_INDEX_SHIFT
;
102 blockIndex
= startBlock
;
103 for (blockIndex
= startBlock
; blockIndex
<= endBlock
; blockIndex
++) {
104 if (blockIndex
< blockLen
&& mBlocks
[blockIndex
])
105 hasBlocksInRange
= true;
107 if (!hasBlocksInRange
) return false;
110 uint32_t i
, start
, end
;
112 // first block, check bits
113 if ((block
= mBlocks
[startBlock
])) {
115 end
= std::min(aEnd
, ((startBlock
+1) << BLOCK_INDEX_SHIFT
) - 1);
116 for (i
= start
; i
<= end
; i
++) {
117 if ((block
->mBits
[(i
>>3) & (BLOCK_SIZE
- 1)]) & (1 << (i
& 0x7)))
121 if (endBlock
== startBlock
) return false;
123 // [2..n-1] blocks check bytes
124 for (blockIndex
= startBlock
+ 1; blockIndex
< endBlock
; blockIndex
++) {
127 if (blockIndex
>= blockLen
|| !(block
= mBlocks
[blockIndex
])) continue;
128 for (index
= 0; index
< BLOCK_SIZE
; index
++) {
129 if (block
->mBits
[index
])
134 // last block, check bits
135 if (endBlock
< blockLen
&& (block
= mBlocks
[endBlock
])) {
136 start
= endBlock
<< BLOCK_INDEX_SHIFT
;
138 for (i
= start
; i
<= end
; i
++) {
139 if ((block
->mBits
[(i
>>3) & (BLOCK_SIZE
- 1)]) & (1 << (i
& 0x7)))
147 void set(uint32_t aIndex
) {
148 uint32_t blockIndex
= aIndex
/BLOCK_SIZE_BITS
;
149 if (blockIndex
>= mBlocks
.Length()) {
150 nsAutoPtr
<Block
> *blocks
= mBlocks
.AppendElements(blockIndex
+ 1 - mBlocks
.Length());
151 if (MOZ_UNLIKELY(!blocks
)) // OOM
154 Block
*block
= mBlocks
[blockIndex
];
157 mBlocks
[blockIndex
] = block
;
159 block
->mBits
[(aIndex
>>3) & (BLOCK_SIZE
- 1)] |= 1 << (aIndex
& 0x7);
162 void set(uint32_t aIndex
, bool aValue
) {
169 void SetRange(uint32_t aStart
, uint32_t aEnd
) {
170 const uint32_t startIndex
= aStart
/BLOCK_SIZE_BITS
;
171 const uint32_t endIndex
= aEnd
/BLOCK_SIZE_BITS
;
173 if (endIndex
>= mBlocks
.Length()) {
174 uint32_t numNewBlocks
= endIndex
+ 1 - mBlocks
.Length();
175 nsAutoPtr
<Block
> *blocks
= mBlocks
.AppendElements(numNewBlocks
);
176 if (MOZ_UNLIKELY(!blocks
)) // OOM
180 for (uint32_t i
= startIndex
; i
<= endIndex
; ++i
) {
181 const uint32_t blockFirstBit
= i
* BLOCK_SIZE_BITS
;
182 const uint32_t blockLastBit
= blockFirstBit
+ BLOCK_SIZE_BITS
- 1;
184 Block
*block
= mBlocks
[i
];
186 bool fullBlock
= false;
187 if (aStart
<= blockFirstBit
&& aEnd
>= blockLastBit
)
190 block
= new Block(fullBlock
? 0xFF : 0);
197 const uint32_t start
= aStart
> blockFirstBit
? aStart
- blockFirstBit
: 0;
198 const uint32_t end
= std::min
<uint32_t>(aEnd
- blockFirstBit
, BLOCK_SIZE_BITS
- 1);
200 for (uint32_t bit
= start
; bit
<= end
; ++bit
) {
201 block
->mBits
[bit
>>3] |= 1 << (bit
& 0x7);
206 void clear(uint32_t aIndex
) {
207 uint32_t blockIndex
= aIndex
/BLOCK_SIZE_BITS
;
208 if (blockIndex
>= mBlocks
.Length()) {
209 nsAutoPtr
<Block
> *blocks
= mBlocks
.AppendElements(blockIndex
+ 1 - mBlocks
.Length());
210 if (MOZ_UNLIKELY(!blocks
)) // OOM
213 Block
*block
= mBlocks
[blockIndex
];
217 block
->mBits
[(aIndex
>>3) & (BLOCK_SIZE
- 1)] &= ~(1 << (aIndex
& 0x7));
220 void ClearRange(uint32_t aStart
, uint32_t aEnd
) {
221 const uint32_t startIndex
= aStart
/BLOCK_SIZE_BITS
;
222 const uint32_t endIndex
= aEnd
/BLOCK_SIZE_BITS
;
224 if (endIndex
>= mBlocks
.Length()) {
225 uint32_t numNewBlocks
= endIndex
+ 1 - mBlocks
.Length();
226 nsAutoPtr
<Block
> *blocks
= mBlocks
.AppendElements(numNewBlocks
);
227 if (MOZ_UNLIKELY(!blocks
)) // OOM
231 for (uint32_t i
= startIndex
; i
<= endIndex
; ++i
) {
232 const uint32_t blockFirstBit
= i
* BLOCK_SIZE_BITS
;
234 Block
*block
= mBlocks
[i
];
236 // any nonexistent block is implicitly all clear,
237 // so there's no need to even create it
241 const uint32_t start
= aStart
> blockFirstBit
? aStart
- blockFirstBit
: 0;
242 const uint32_t end
= std::min
<uint32_t>(aEnd
- blockFirstBit
, BLOCK_SIZE_BITS
- 1);
244 for (uint32_t bit
= start
; bit
<= end
; ++bit
) {
245 block
->mBits
[bit
>>3] &= ~(1 << (bit
& 0x7));
250 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const {
251 size_t total
= mBlocks
.SizeOfExcludingThis(aMallocSizeOf
);
252 for (uint32_t i
= 0; i
< mBlocks
.Length(); i
++) {
254 total
+= aMallocSizeOf(mBlocks
[i
]);
260 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const {
261 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf
);
264 // clear out all blocks in the array
267 for (i
= 0; i
< mBlocks
.Length(); i
++)
268 mBlocks
[i
] = nullptr;
271 // set this bitset to the union of its current contents and another
272 void Union(const gfxSparseBitSet
& aBitset
) {
273 // ensure mBlocks is large enough
274 uint32_t blockCount
= aBitset
.mBlocks
.Length();
275 if (blockCount
> mBlocks
.Length()) {
276 uint32_t needed
= blockCount
- mBlocks
.Length();
277 nsAutoPtr
<Block
> *blocks
= mBlocks
.AppendElements(needed
);
278 if (MOZ_UNLIKELY(!blocks
)) { // OOM
282 // for each block that may be present in aBitset...
283 for (uint32_t i
= 0; i
< blockCount
; ++i
) {
284 // if it is missing (implicitly empty), just skip
285 if (!aBitset
.mBlocks
[i
]) {
288 // if the block is missing in this set, just copy the other
290 mBlocks
[i
] = new Block(*aBitset
.mBlocks
[i
]);
293 // else set existing block to the union of both
294 uint32_t *dst
= reinterpret_cast<uint32_t*>(mBlocks
[i
]->mBits
);
295 const uint32_t *src
=
296 reinterpret_cast<const uint32_t*>(aBitset
.mBlocks
[i
]->mBits
);
297 for (uint32_t j
= 0; j
< BLOCK_SIZE
/ 4; ++j
) {
307 uint32_t GetChecksum() const {
308 uint32_t check
= adler32(0, Z_NULL
, 0);
309 for (uint32_t i
= 0; i
< mBlocks
.Length(); i
++) {
311 const Block
*block
= mBlocks
[i
];
312 check
= adler32(check
, (uint8_t*) (&i
), 4);
313 check
= adler32(check
, (uint8_t*) block
, sizeof(Block
));
320 nsTArray
< nsAutoPtr
<Block
> > mBlocks
;
323 #define TRUETYPE_TAG(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
327 // Byte-swapping types and name table structure definitions moved from
328 // gfxFontUtils.cpp to .h file so that gfxFont.cpp can also refer to them
331 struct AutoSwap_PRUint16
{
333 AutoSwap_PRUint16
& operator = (const uint16_t aValue
)
335 this->value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
339 MOZ_IMPLICIT
AutoSwap_PRUint16(uint16_t aValue
)
341 value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
344 operator uint16_t() const
346 return mozilla::NativeEndian::swapFromBigEndian(value
);
349 operator uint32_t() const
351 return mozilla::NativeEndian::swapFromBigEndian(value
);
354 operator uint64_t() const
356 return mozilla::NativeEndian::swapFromBigEndian(value
);
363 struct AutoSwap_PRInt16
{
365 AutoSwap_PRInt16
& operator = (const int16_t aValue
)
367 this->value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
371 MOZ_IMPLICIT
AutoSwap_PRInt16(int16_t aValue
)
373 value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
376 operator int16_t() const
378 return mozilla::NativeEndian::swapFromBigEndian(value
);
381 operator uint32_t() const
383 return mozilla::NativeEndian::swapFromBigEndian(value
);
390 struct AutoSwap_PRUint32
{
392 AutoSwap_PRUint32
& operator = (const uint32_t aValue
)
394 this->value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
398 MOZ_IMPLICIT
AutoSwap_PRUint32(uint32_t aValue
)
400 value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
403 operator uint32_t() const
405 return mozilla::NativeEndian::swapFromBigEndian(value
);
412 struct AutoSwap_PRInt32
{
414 AutoSwap_PRInt32
& operator = (const int32_t aValue
)
416 this->value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
420 MOZ_IMPLICIT
AutoSwap_PRInt32(int32_t aValue
)
422 value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
425 operator int32_t() const
427 return mozilla::NativeEndian::swapFromBigEndian(value
);
434 struct AutoSwap_PRUint64
{
436 AutoSwap_PRUint64
& operator = (const uint64_t aValue
)
438 this->value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
442 MOZ_IMPLICIT
AutoSwap_PRUint64(uint64_t aValue
)
444 value
= mozilla::NativeEndian::swapToBigEndian(aValue
);
447 operator uint64_t() const
449 return mozilla::NativeEndian::swapFromBigEndian(value
);
456 struct AutoSwap_PRUint24
{
457 operator uint32_t() const { return value
[0] << 16 | value
[1] << 8 | value
[2]; }
459 AutoSwap_PRUint24() { }
464 AutoSwap_PRUint32 sfntVersion
; // Fixed, 0x00010000 for version 1.0.
465 AutoSwap_PRUint16 numTables
; // Number of tables.
466 AutoSwap_PRUint16 searchRange
; // (Maximum power of 2 <= numTables) x 16.
467 AutoSwap_PRUint16 entrySelector
; // Log2(maximum power of 2 <= numTables).
468 AutoSwap_PRUint16 rangeShift
; // NumTables x 16-searchRange.
471 struct TableDirEntry
{
472 AutoSwap_PRUint32 tag
; // 4 -byte identifier.
473 AutoSwap_PRUint32 checkSum
; // CheckSum for this table.
474 AutoSwap_PRUint32 offset
; // Offset from beginning of TrueType font file.
475 AutoSwap_PRUint32 length
; // Length of this table.
480 HEAD_VERSION
= 0x00010000,
481 HEAD_MAGIC_NUMBER
= 0x5F0F3CF5,
482 HEAD_CHECKSUM_CALC_CONST
= 0xB1B0AFBA
485 AutoSwap_PRUint32 tableVersionNumber
; // Fixed, 0x00010000 for version 1.0.
486 AutoSwap_PRUint32 fontRevision
; // Set by font manufacturer.
487 AutoSwap_PRUint32 checkSumAdjustment
; // To compute: set it to 0, sum the entire font as ULONG, then store 0xB1B0AFBA - sum.
488 AutoSwap_PRUint32 magicNumber
; // Set to 0x5F0F3CF5.
489 AutoSwap_PRUint16 flags
;
490 AutoSwap_PRUint16 unitsPerEm
; // Valid range is from 16 to 16384. This value should be a power of 2 for fonts that have TrueType outlines.
491 AutoSwap_PRUint64 created
; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
492 AutoSwap_PRUint64 modified
; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
493 AutoSwap_PRInt16 xMin
; // For all glyph bounding boxes.
494 AutoSwap_PRInt16 yMin
; // For all glyph bounding boxes.
495 AutoSwap_PRInt16 xMax
; // For all glyph bounding boxes.
496 AutoSwap_PRInt16 yMax
; // For all glyph bounding boxes.
497 AutoSwap_PRUint16 macStyle
; // Bit 0: Bold (if set to 1);
498 AutoSwap_PRUint16 lowestRecPPEM
; // Smallest readable size in pixels.
499 AutoSwap_PRInt16 fontDirectionHint
;
500 AutoSwap_PRInt16 indexToLocFormat
;
501 AutoSwap_PRInt16 glyphDataFormat
;
505 AutoSwap_PRUint16 version
; // 0004 = OpenType 1.5
506 AutoSwap_PRInt16 xAvgCharWidth
;
507 AutoSwap_PRUint16 usWeightClass
;
508 AutoSwap_PRUint16 usWidthClass
;
509 AutoSwap_PRUint16 fsType
;
510 AutoSwap_PRInt16 ySubscriptXSize
;
511 AutoSwap_PRInt16 ySubscriptYSize
;
512 AutoSwap_PRInt16 ySubscriptXOffset
;
513 AutoSwap_PRInt16 ySubscriptYOffset
;
514 AutoSwap_PRInt16 ySuperscriptXSize
;
515 AutoSwap_PRInt16 ySuperscriptYSize
;
516 AutoSwap_PRInt16 ySuperscriptXOffset
;
517 AutoSwap_PRInt16 ySuperscriptYOffset
;
518 AutoSwap_PRInt16 yStrikeoutSize
;
519 AutoSwap_PRInt16 yStrikeoutPosition
;
520 AutoSwap_PRInt16 sFamilyClass
;
522 AutoSwap_PRUint32 unicodeRange1
;
523 AutoSwap_PRUint32 unicodeRange2
;
524 AutoSwap_PRUint32 unicodeRange3
;
525 AutoSwap_PRUint32 unicodeRange4
;
526 uint8_t achVendID
[4];
527 AutoSwap_PRUint16 fsSelection
;
528 AutoSwap_PRUint16 usFirstCharIndex
;
529 AutoSwap_PRUint16 usLastCharIndex
;
530 AutoSwap_PRInt16 sTypoAscender
;
531 AutoSwap_PRInt16 sTypoDescender
;
532 AutoSwap_PRInt16 sTypoLineGap
;
533 AutoSwap_PRUint16 usWinAscent
;
534 AutoSwap_PRUint16 usWinDescent
;
535 AutoSwap_PRUint32 codePageRange1
;
536 AutoSwap_PRUint32 codePageRange2
;
537 AutoSwap_PRInt16 sxHeight
;
538 AutoSwap_PRInt16 sCapHeight
;
539 AutoSwap_PRUint16 usDefaultChar
;
540 AutoSwap_PRUint16 usBreakChar
;
541 AutoSwap_PRUint16 usMaxContext
;
545 AutoSwap_PRUint32 version
;
546 AutoSwap_PRInt32 italicAngle
;
547 AutoSwap_PRInt16 underlinePosition
;
548 AutoSwap_PRUint16 underlineThickness
;
549 AutoSwap_PRUint32 isFixedPitch
;
550 AutoSwap_PRUint32 minMemType42
;
551 AutoSwap_PRUint32 maxMemType42
;
552 AutoSwap_PRUint32 minMemType1
;
553 AutoSwap_PRUint32 maxMemType1
;
557 AutoSwap_PRUint32 version
;
558 AutoSwap_PRInt16 ascender
;
559 AutoSwap_PRInt16 descender
;
560 AutoSwap_PRInt16 lineGap
;
561 AutoSwap_PRUint16 advanceWidthMax
;
562 AutoSwap_PRInt16 minLeftSideBearing
;
563 AutoSwap_PRInt16 minRightSideBearing
;
564 AutoSwap_PRInt16 xMaxExtent
;
565 AutoSwap_PRInt16 caretSlopeRise
;
566 AutoSwap_PRInt16 caretSlopeRun
;
567 AutoSwap_PRInt16 caretOffset
;
568 AutoSwap_PRInt16 reserved1
;
569 AutoSwap_PRInt16 reserved2
;
570 AutoSwap_PRInt16 reserved3
;
571 AutoSwap_PRInt16 reserved4
;
572 AutoSwap_PRInt16 metricDataFormat
;
573 AutoSwap_PRUint16 numOfLongHorMetrics
;
576 struct MaxpTableHeader
{
577 AutoSwap_PRUint32 version
; // CFF: 0x00005000; TrueType: 0x00010000
578 AutoSwap_PRUint16 numGlyphs
;
579 // truetype version has additional fields that we don't currently use
582 // old 'kern' table, supported on Windows
583 // see http://www.microsoft.com/typography/otspec/kern.htm
584 struct KernTableVersion0
{
585 AutoSwap_PRUint16 version
; // 0x0000
586 AutoSwap_PRUint16 nTables
;
589 struct KernTableSubtableHeaderVersion0
{
590 AutoSwap_PRUint16 version
;
591 AutoSwap_PRUint16 length
;
592 AutoSwap_PRUint16 coverage
;
595 // newer Mac-only 'kern' table, ignored by Windows
596 // see http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6kern.html
597 struct KernTableVersion1
{
598 AutoSwap_PRUint32 version
; // 0x00010000
599 AutoSwap_PRUint32 nTables
;
602 struct KernTableSubtableHeaderVersion1
{
603 AutoSwap_PRUint32 length
;
604 AutoSwap_PRUint16 coverage
;
605 AutoSwap_PRUint16 tupleIndex
;
609 AutoSwap_PRUint16 version
;
610 AutoSwap_PRUint16 numBaseGlyphRecord
;
611 AutoSwap_PRUint32 offsetBaseGlyphRecord
;
612 AutoSwap_PRUint32 offsetLayerRecord
;
613 AutoSwap_PRUint16 numLayerRecords
;
616 struct CPALHeaderVersion0
{
617 AutoSwap_PRUint16 version
;
618 AutoSwap_PRUint16 numPaletteEntries
;
619 AutoSwap_PRUint16 numPalettes
;
620 AutoSwap_PRUint16 numColorRecords
;
621 AutoSwap_PRUint32 offsetFirstColorRecord
;
626 // Return just the highest bit of the given value, i.e., the highest
627 // power of 2 that is <= value, or zero if the input value is zero.
629 FindHighestBit(uint32_t value
)
631 // propagate highest bit into all lower bits of the value
632 value
|= (value
>> 1);
633 value
|= (value
>> 2);
634 value
|= (value
>> 4);
635 value
|= (value
>> 8);
636 value
|= (value
>> 16);
637 // isolate the leftmost bit
638 return (value
& ~(value
>> 1));
641 } // namespace mozilla
643 // used for overlaying name changes without touching original font data
644 struct FontDataOverlay
{
645 // overlaySrc != 0 ==> use overlay
646 uint32_t overlaySrc
; // src offset from start of font data
647 uint32_t overlaySrcLen
; // src length
648 uint32_t overlayDest
; // dest offset from start of font data
651 enum gfxUserFontType
{
652 GFX_USERFONT_UNKNOWN
= 0,
653 GFX_USERFONT_OPENTYPE
= 1,
654 GFX_USERFONT_SVG
= 2,
655 GFX_USERFONT_WOFF
= 3
658 extern const uint8_t sCJKCompatSVSTable
[];
663 // these are public because gfxFont.cpp also looks into the name table
670 NAME_ID_POSTSCRIPT
= 6,
671 NAME_ID_PREFERRED_FAMILY
= 16,
672 NAME_ID_PREFERRED_STYLE
= 17,
675 PLATFORM_ID_UNICODE
= 0, // Mac OS uses this typically
678 PLATFORM_ID_MICROSOFT
= 3,
680 ENCODING_ID_MAC_ROMAN
= 0, // traditional Mac OS script manager encodings
681 ENCODING_ID_MAC_JAPANESE
= 1, // (there are others defined, but some were never
682 ENCODING_ID_MAC_TRAD_CHINESE
= 2, // implemented by Apple, and I have never seen them
683 ENCODING_ID_MAC_KOREAN
= 3, // used in font names)
684 ENCODING_ID_MAC_ARABIC
= 4,
685 ENCODING_ID_MAC_HEBREW
= 5,
686 ENCODING_ID_MAC_GREEK
= 6,
687 ENCODING_ID_MAC_CYRILLIC
= 7,
688 ENCODING_ID_MAC_DEVANAGARI
= 9,
689 ENCODING_ID_MAC_GURMUKHI
= 10,
690 ENCODING_ID_MAC_GUJARATI
= 11,
691 ENCODING_ID_MAC_SIMP_CHINESE
= 25,
693 ENCODING_ID_MICROSOFT_SYMBOL
= 0, // Microsoft platform encoding IDs
694 ENCODING_ID_MICROSOFT_UNICODEBMP
= 1,
695 ENCODING_ID_MICROSOFT_SHIFTJIS
= 2,
696 ENCODING_ID_MICROSOFT_PRC
= 3,
697 ENCODING_ID_MICROSOFT_BIG5
= 4,
698 ENCODING_ID_MICROSOFT_WANSUNG
= 5,
699 ENCODING_ID_MICROSOFT_JOHAB
= 6,
700 ENCODING_ID_MICROSOFT_UNICODEFULL
= 10,
703 LANG_ID_MAC_ENGLISH
= 0, // many others are defined, but most don't affect
704 LANG_ID_MAC_HEBREW
= 10, // the charset; should check all the central/eastern
705 LANG_ID_MAC_JAPANESE
= 11, // european codes, though
706 LANG_ID_MAC_ARABIC
= 12,
707 LANG_ID_MAC_ICELANDIC
= 15,
708 LANG_ID_MAC_TURKISH
= 17,
709 LANG_ID_MAC_TRAD_CHINESE
= 19,
710 LANG_ID_MAC_URDU
= 20,
711 LANG_ID_MAC_KOREAN
= 23,
712 LANG_ID_MAC_POLISH
= 25,
713 LANG_ID_MAC_FARSI
= 31,
714 LANG_ID_MAC_SIMP_CHINESE
= 33,
715 LANG_ID_MAC_ROMANIAN
= 37,
716 LANG_ID_MAC_CZECH
= 38,
717 LANG_ID_MAC_SLOVAK
= 39,
719 LANG_ID_MICROSOFT_EN_US
= 0x0409, // with Microsoft platformID, EN US lang code
721 CMAP_MAX_CODEPOINT
= 0x10ffff // maximum possible Unicode codepoint
722 // contained in a cmap
725 // name table has a header, followed by name records, followed by string data
727 mozilla::AutoSwap_PRUint16 format
; // Format selector (=0).
728 mozilla::AutoSwap_PRUint16 count
; // Number of name records.
729 mozilla::AutoSwap_PRUint16 stringOffset
; // Offset to start of string storage
730 // (from start of table)
734 mozilla::AutoSwap_PRUint16 platformID
; // Platform ID
735 mozilla::AutoSwap_PRUint16 encodingID
; // Platform-specific encoding ID
736 mozilla::AutoSwap_PRUint16 languageID
; // Language ID
737 mozilla::AutoSwap_PRUint16 nameID
; // Name ID.
738 mozilla::AutoSwap_PRUint16 length
; // String length (in bytes).
739 mozilla::AutoSwap_PRUint16 offset
; // String offset from start of storage
743 // for reading big-endian font data on either big or little-endian platforms
745 static inline uint16_t
746 ReadShortAt(const uint8_t *aBuf
, uint32_t aIndex
)
748 return (aBuf
[aIndex
] << 8) | aBuf
[aIndex
+ 1];
751 static inline uint16_t
752 ReadShortAt16(const uint16_t *aBuf
, uint32_t aIndex
)
754 const uint8_t *buf
= reinterpret_cast<const uint8_t*>(aBuf
);
755 uint32_t index
= aIndex
<< 1;
756 return (buf
[index
] << 8) | buf
[index
+1];
759 static inline uint32_t
760 ReadUint24At(const uint8_t *aBuf
, uint32_t aIndex
)
762 return ((aBuf
[aIndex
] << 16) | (aBuf
[aIndex
+ 1] << 8) |
766 static inline uint32_t
767 ReadLongAt(const uint8_t *aBuf
, uint32_t aIndex
)
769 return ((aBuf
[aIndex
] << 24) | (aBuf
[aIndex
+ 1] << 16) |
770 (aBuf
[aIndex
+ 2] << 8) | (aBuf
[aIndex
+ 3]));
774 ReadCMAPTableFormat12(const uint8_t *aBuf
, uint32_t aLength
,
775 gfxSparseBitSet
& aCharacterMap
);
778 ReadCMAPTableFormat4(const uint8_t *aBuf
, uint32_t aLength
,
779 gfxSparseBitSet
& aCharacterMap
);
782 ReadCMAPTableFormat14(const uint8_t *aBuf
, uint32_t aLength
,
786 FindPreferredSubtable(const uint8_t *aBuf
, uint32_t aBufLength
,
787 uint32_t *aTableOffset
, uint32_t *aUVSTableOffset
,
788 bool *aSymbolEncoding
);
791 ReadCMAP(const uint8_t *aBuf
, uint32_t aBufLength
,
792 gfxSparseBitSet
& aCharacterMap
,
793 uint32_t& aUVSOffset
,
794 bool& aUnicodeFont
, bool& aSymbolFont
);
797 MapCharToGlyphFormat4(const uint8_t *aBuf
, char16_t aCh
);
800 MapCharToGlyphFormat12(const uint8_t *aBuf
, uint32_t aCh
);
803 MapUVSToGlyphFormat14(const uint8_t *aBuf
, uint32_t aCh
, uint32_t aVS
);
805 // sCJKCompatSVSTable is a 'cmap' format 14 subtable that maps
806 // <char + var-selector> pairs to the corresponding Unicode
807 // compatibility ideograph codepoints.
808 static MOZ_ALWAYS_INLINE
uint32_t
809 GetUVSFallback(uint32_t aCh
, uint32_t aVS
) {
810 aCh
= MapUVSToGlyphFormat14(sCJKCompatSVSTable
, aCh
, aVS
);
811 return aCh
>= 0xFB00 ? aCh
+ (0x2F800 - 0xFB00) : aCh
;
815 MapCharToGlyph(const uint8_t *aCmapBuf
, uint32_t aBufLength
,
816 uint32_t aUnicode
, uint32_t aVarSelector
= 0);
819 // determine whether a font (which has already been sanitized, so is known
820 // to be a valid sfnt) is CFF format rather than TrueType
822 IsCffFont(const uint8_t* aFontData
);
825 // determine the format of font data
826 static gfxUserFontType
827 DetermineFontDataType(const uint8_t *aFontData
, uint32_t aFontDataLength
);
829 // Read the fullname from the sfnt data (used to save the original name
830 // prior to renaming the font for installation).
831 // This is called with sfnt data that has already been validated,
832 // so it should always succeed in finding the name table.
834 GetFullNameFromSFNT(const uint8_t* aFontData
, uint32_t aLength
,
835 nsAString
& aFullName
);
837 // helper to get fullname from name table, constructing from family+style
838 // if no explicit fullname is present
840 GetFullNameFromTable(hb_blob_t
*aNameTable
,
841 nsAString
& aFullName
);
843 // helper to get family name from name table
845 GetFamilyNameFromTable(hb_blob_t
*aNameTable
,
846 nsAString
& aFamilyName
);
848 // create a new name table and build a new font with that name table
849 // appended on the end, returns true on success
851 RenameFont(const nsAString
& aName
, const uint8_t *aFontData
,
852 uint32_t aFontDataLength
, FallibleTArray
<uint8_t> *aNewFont
);
854 // read all names matching aNameID, returning in aNames array
856 ReadNames(const char *aNameData
, uint32_t aDataLen
, uint32_t aNameID
,
857 int32_t aPlatformID
, nsTArray
<nsString
>& aNames
);
859 // reads English or first name matching aNameID, returning in aName
860 // platform based on OS
862 ReadCanonicalName(hb_blob_t
*aNameTable
, uint32_t aNameID
,
866 ReadCanonicalName(const char *aNameData
, uint32_t aDataLen
,
867 uint32_t aNameID
, nsString
& aName
);
869 // convert a name from the raw name table data into an nsString,
870 // provided we know how; return true if successful, or false
871 // if we can't handle the encoding
873 DecodeFontName(const char *aBuf
, int32_t aLength
,
874 uint32_t aPlatformCode
, uint32_t aScriptCode
,
875 uint32_t aLangCode
, nsAString
& dest
);
877 static inline bool IsJoinCauser(uint32_t ch
) {
878 return (ch
== 0x200D);
881 static inline bool IsJoinControl(uint32_t ch
) {
882 return (ch
== 0x200C || ch
== 0x200D);
886 kUnicodeVS1
= 0xFE00,
887 kUnicodeVS16
= 0xFE0F,
888 kUnicodeVS17
= 0xE0100,
889 kUnicodeVS256
= 0xE01EF
892 static inline bool IsVarSelector(uint32_t ch
) {
893 return (ch
>= kUnicodeVS1
&& ch
<= kUnicodeVS16
) ||
894 (ch
>= kUnicodeVS17
&& ch
<= kUnicodeVS256
);
897 static inline bool IsInvalid(uint32_t ch
) {
898 return (ch
== 0xFFFD);
901 // Font code may want to know if there is the potential for bidi behavior
902 // to be triggered by any of the characters in a text run; this can be
903 // used to test that possibility.
905 kUnicodeBidiScriptsStart
= 0x0590,
906 kUnicodeBidiScriptsEnd
= 0x08FF,
907 kUnicodeBidiPresentationStart
= 0xFB1D,
908 kUnicodeBidiPresentationEnd
= 0xFEFC,
909 kUnicodeFirstHighSurrogateBlock
= 0xD800,
910 kUnicodeRLM
= 0x200F,
911 kUnicodeRLE
= 0x202B,
915 static inline bool PotentialRTLChar(char16_t aCh
) {
916 if (aCh
>= kUnicodeBidiScriptsStart
&& aCh
<= kUnicodeBidiScriptsEnd
)
917 // bidi scripts Hebrew, Arabic, Syriac, Thaana, N'Ko are all encoded together
920 if (aCh
== kUnicodeRLM
|| aCh
== kUnicodeRLE
|| aCh
== kUnicodeRLO
)
921 // directional controls that trigger bidi layout
924 if (aCh
>= kUnicodeBidiPresentationStart
&&
925 aCh
<= kUnicodeBidiPresentationEnd
)
926 // presentation forms of Arabic and Hebrew letters
929 if ((aCh
& 0xFF00) == kUnicodeFirstHighSurrogateBlock
)
930 // surrogate that could be part of a bidi supplementary char
931 // (Cypriot, Aramaic, Phoenecian, etc)
934 // otherwise we know this char cannot trigger bidi reordering
938 // parse a simple list of font family names into
939 // an array of strings
940 static void ParseFontList(const nsAString
& aFamilyList
,
941 nsTArray
<nsString
>& aFontList
);
943 // for a given font list pref name, append list of font names
944 static void AppendPrefsFontList(const char *aPrefName
,
945 nsTArray
<nsString
>& aFontList
);
947 // for a given font list pref name, initialize a list of font names
948 static void GetPrefsFontList(const char *aPrefName
,
949 nsTArray
<nsString
>& aFontList
);
951 // generate a unique font name
952 static nsresult
MakeUniqueUserFontName(nsAString
& aName
);
954 // for color layer from glyph using COLR and CPAL tables
955 static bool ValidateColorGlyphs(hb_blob_t
* aCOLR
, hb_blob_t
* aCPAL
);
956 static bool GetColorGlyphLayers(hb_blob_t
* aCOLR
,
959 nsTArray
<uint16_t> &aGlyphs
,
960 nsTArray
<mozilla::gfx::Color
> &aColors
);
964 ReadNames(const char *aNameData
, uint32_t aDataLen
, uint32_t aNameID
,
965 int32_t aLangID
, int32_t aPlatformID
, nsTArray
<nsString
>& aNames
);
967 // convert opentype name-table platform/encoding/language values to a charset name
968 // we can use to convert the name data to unicode, or "" if data is UTF16BE
970 GetCharsetForFontName(uint16_t aPlatform
, uint16_t aScript
, uint16_t aLanguage
);
972 struct MacFontNameCharsetMapping
{
975 const char *mCharsetName
;
977 bool operator<(const MacFontNameCharsetMapping
& rhs
) const {
978 return (mEncoding
< rhs
.mEncoding
) ||
979 ((mEncoding
== rhs
.mEncoding
) && (mLanguage
< rhs
.mLanguage
));
982 static const MacFontNameCharsetMapping gMacFontNameCharsets
[];
983 static const char* gISOFontNameCharsets
[];
984 static const char* gMSFontNameCharsets
[];
988 #endif /* GFX_FONT_UTILS_H */