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