gfxFontUtils.h 35 KB

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