nsFontFace.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #include "nsFontFace.h"
  5. #include "nsIDOMCSSFontFaceRule.h"
  6. #include "nsCSSRules.h"
  7. #include "gfxTextRun.h"
  8. #include "gfxUserFontSet.h"
  9. #include "nsFontFaceLoader.h"
  10. #include "mozilla/gfx/2D.h"
  11. #include "brotli/decode.h"
  12. #include "zlib.h"
  13. #include "mozilla/dom/FontFaceSet.h"
  14. using namespace mozilla;
  15. using namespace mozilla::dom;
  16. nsFontFace::nsFontFace(gfxFontEntry* aFontEntry,
  17. gfxFontGroup* aFontGroup,
  18. uint8_t aMatchType)
  19. : mFontEntry(aFontEntry),
  20. mFontGroup(aFontGroup),
  21. mMatchType(aMatchType)
  22. {
  23. }
  24. nsFontFace::~nsFontFace()
  25. {
  26. }
  27. ////////////////////////////////////////////////////////////////////////
  28. // nsISupports
  29. NS_IMPL_ISUPPORTS(nsFontFace, nsIDOMFontFace)
  30. ////////////////////////////////////////////////////////////////////////
  31. // nsIDOMFontFace
  32. NS_IMETHODIMP
  33. nsFontFace::GetFromFontGroup(bool * aFromFontGroup)
  34. {
  35. *aFromFontGroup =
  36. (mMatchType & gfxTextRange::kFontGroup) != 0;
  37. return NS_OK;
  38. }
  39. NS_IMETHODIMP
  40. nsFontFace::GetFromLanguagePrefs(bool * aFromLanguagePrefs)
  41. {
  42. *aFromLanguagePrefs =
  43. (mMatchType & gfxTextRange::kPrefsFallback) != 0;
  44. return NS_OK;
  45. }
  46. NS_IMETHODIMP
  47. nsFontFace::GetFromSystemFallback(bool * aFromSystemFallback)
  48. {
  49. *aFromSystemFallback =
  50. (mMatchType & gfxTextRange::kSystemFallback) != 0;
  51. return NS_OK;
  52. }
  53. NS_IMETHODIMP
  54. nsFontFace::GetName(nsAString & aName)
  55. {
  56. if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
  57. NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
  58. aName = mFontEntry->mUserFontData->mRealName;
  59. } else {
  60. aName = mFontEntry->RealFaceName();
  61. }
  62. return NS_OK;
  63. }
  64. NS_IMETHODIMP
  65. nsFontFace::GetCSSFamilyName(nsAString & aCSSFamilyName)
  66. {
  67. aCSSFamilyName = mFontEntry->FamilyName();
  68. return NS_OK;
  69. }
  70. NS_IMETHODIMP
  71. nsFontFace::GetRule(nsIDOMCSSFontFaceRule **aRule)
  72. {
  73. // check whether this font entry is associated with an @font-face rule
  74. // in the relevant font group's user font set
  75. nsCSSFontFaceRule* rule = nullptr;
  76. if (mFontEntry->IsUserFont()) {
  77. FontFaceSet::UserFontSet* fontSet =
  78. static_cast<FontFaceSet::UserFontSet*>(mFontGroup->GetUserFontSet());
  79. if (fontSet) {
  80. FontFaceSet* fontFaceSet = fontSet->GetFontFaceSet();
  81. if (fontFaceSet) {
  82. rule = fontFaceSet->FindRuleForEntry(mFontEntry);
  83. }
  84. }
  85. }
  86. NS_IF_ADDREF(*aRule = rule);
  87. return NS_OK;
  88. }
  89. NS_IMETHODIMP
  90. nsFontFace::GetSrcIndex(int32_t * aSrcIndex)
  91. {
  92. if (mFontEntry->IsUserFont()) {
  93. NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
  94. *aSrcIndex = mFontEntry->mUserFontData->mSrcIndex;
  95. } else {
  96. *aSrcIndex = -1;
  97. }
  98. return NS_OK;
  99. }
  100. NS_IMETHODIMP
  101. nsFontFace::GetURI(nsAString & aURI)
  102. {
  103. aURI.Truncate();
  104. if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
  105. NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
  106. if (mFontEntry->mUserFontData->mURI) {
  107. nsAutoCString spec;
  108. nsresult rv = mFontEntry->mUserFontData->mURI->GetSpec(spec);
  109. NS_ENSURE_SUCCESS(rv, rv);
  110. AppendUTF8toUTF16(spec, aURI);
  111. }
  112. }
  113. return NS_OK;
  114. }
  115. NS_IMETHODIMP
  116. nsFontFace::GetLocalName(nsAString & aLocalName)
  117. {
  118. if (mFontEntry->IsLocalUserFont()) {
  119. NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
  120. aLocalName = mFontEntry->mUserFontData->mLocalName;
  121. } else {
  122. aLocalName.Truncate();
  123. }
  124. return NS_OK;
  125. }
  126. static void
  127. AppendToFormat(nsAString & aResult, const char* aFormat)
  128. {
  129. if (!aResult.IsEmpty()) {
  130. aResult.Append(',');
  131. }
  132. aResult.AppendASCII(aFormat);
  133. }
  134. NS_IMETHODIMP
  135. nsFontFace::GetFormat(nsAString & aFormat)
  136. {
  137. aFormat.Truncate();
  138. if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
  139. NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
  140. uint32_t formatFlags = mFontEntry->mUserFontData->mFormat;
  141. if (formatFlags & gfxUserFontSet::FLAG_FORMAT_OPENTYPE) {
  142. AppendToFormat(aFormat, "opentype");
  143. }
  144. if (formatFlags & gfxUserFontSet::FLAG_FORMAT_TRUETYPE) {
  145. AppendToFormat(aFormat, "truetype");
  146. }
  147. if (formatFlags & gfxUserFontSet::FLAG_FORMAT_TRUETYPE_AAT) {
  148. AppendToFormat(aFormat, "truetype-aat");
  149. }
  150. if (formatFlags & gfxUserFontSet::FLAG_FORMAT_EOT) {
  151. AppendToFormat(aFormat, "embedded-opentype");
  152. }
  153. if (formatFlags & gfxUserFontSet::FLAG_FORMAT_SVG) {
  154. AppendToFormat(aFormat, "svg");
  155. }
  156. if (formatFlags & gfxUserFontSet::FLAG_FORMAT_WOFF) {
  157. AppendToFormat(aFormat, "woff");
  158. }
  159. if (formatFlags & gfxUserFontSet::FLAG_FORMAT_WOFF2) {
  160. AppendToFormat(aFormat, "woff2");
  161. }
  162. }
  163. return NS_OK;
  164. }
  165. NS_IMETHODIMP
  166. nsFontFace::GetMetadata(nsAString & aMetadata)
  167. {
  168. aMetadata.Truncate();
  169. if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
  170. NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
  171. const gfxUserFontData* userFontData = mFontEntry->mUserFontData.get();
  172. if (userFontData->mMetadata.Length() && userFontData->mMetaOrigLen) {
  173. nsAutoCString str;
  174. str.SetLength(userFontData->mMetaOrigLen);
  175. if (str.Length() == userFontData->mMetaOrigLen) {
  176. switch (userFontData->mCompression) {
  177. case gfxUserFontData::kZlibCompression:
  178. {
  179. uLongf destLen = userFontData->mMetaOrigLen;
  180. if (uncompress((Bytef *)(str.BeginWriting()), &destLen,
  181. (const Bytef *)(userFontData->mMetadata.Elements()),
  182. userFontData->mMetadata.Length()) == Z_OK &&
  183. destLen == userFontData->mMetaOrigLen) {
  184. AppendUTF8toUTF16(str, aMetadata);
  185. }
  186. }
  187. break;
  188. case gfxUserFontData::kBrotliCompression:
  189. {
  190. size_t decodedSize = userFontData->mMetaOrigLen;
  191. if (BrotliDecoderDecompress(userFontData->mMetadata.Length(),
  192. userFontData->mMetadata.Elements(),
  193. &decodedSize,
  194. (uint8_t*)str.BeginWriting()) == 1 &&
  195. decodedSize == userFontData->mMetaOrigLen) {
  196. AppendUTF8toUTF16(str, aMetadata);
  197. }
  198. }
  199. break;
  200. }
  201. }
  202. }
  203. }
  204. return NS_OK;
  205. }