Backed out changeset 496886cb30a5 (bug 1867152) for bc failures on browser_user_input...
[gecko.git] / layout / inspector / InspectorFontFace.cpp
blob59a336fd1b39aa783f2a828f292c9dee8ab81132
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "InspectorFontFace.h"
9 #include "gfxPlatformFontList.h"
10 #include "gfxTextRun.h"
11 #include "gfxUserFontSet.h"
12 #include "nsFontFaceLoader.h"
13 #include "mozilla/gfx/2D.h"
14 #include "brotli/decode.h"
15 #include "zlib.h"
16 #include "mozilla/dom/CSSFontFaceRule.h"
17 #include "mozilla/dom/FontFaceSet.h"
18 #include "mozilla/ServoBindings.h"
19 #include "mozilla/Unused.h"
21 namespace mozilla {
22 namespace dom {
24 InspectorFontFace::InspectorFontFace(gfxFontEntry* aFontEntry,
25 gfxFontGroup* aFontGroup,
26 FontMatchType aMatchType)
27 : mFontEntry(aFontEntry), mFontGroup(aFontGroup), mMatchType(aMatchType) {
28 MOZ_COUNT_CTOR(InspectorFontFace);
31 InspectorFontFace::~InspectorFontFace() { MOZ_COUNT_DTOR(InspectorFontFace); }
33 bool InspectorFontFace::FromFontGroup() {
34 return bool(mMatchType.kind & FontMatchType::Kind::kFontGroup);
37 bool InspectorFontFace::FromLanguagePrefs() {
38 return bool(mMatchType.kind & FontMatchType::Kind::kPrefsFallback);
41 bool InspectorFontFace::FromSystemFallback() {
42 return bool(mMatchType.kind & FontMatchType::Kind::kSystemFallback);
45 void InspectorFontFace::GetName(nsAString& aName) {
46 if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
47 NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
48 aName.Append(NS_ConvertUTF8toUTF16(mFontEntry->mUserFontData->mRealName));
49 } else {
50 aName.Append(NS_ConvertUTF8toUTF16(mFontEntry->RealFaceName()));
54 void InspectorFontFace::GetCSSFamilyName(nsAString& aCSSFamilyName) {
55 aCSSFamilyName.Append(NS_ConvertUTF8toUTF16(mFontEntry->FamilyName()));
58 void InspectorFontFace::GetCSSGeneric(nsAString& aName) {
59 if (mMatchType.generic != StyleGenericFontFamily::None) {
60 aName.AssignASCII(gfxPlatformFontList::GetGenericName(mMatchType.generic));
61 } else {
62 aName.Truncate(0);
66 CSSFontFaceRule* InspectorFontFace::GetRule() {
67 if (!mRule) {
68 // check whether this font entry is associated with an @font-face rule
69 // in the relevant font group's user font set
70 StyleLockedFontFaceRule* rule = nullptr;
71 if (mFontEntry->IsUserFont()) {
72 auto* fontFaceSet =
73 static_cast<FontFaceSetImpl*>(mFontGroup->GetUserFontSet());
74 if (fontFaceSet) {
75 rule = fontFaceSet->FindRuleForEntry(mFontEntry);
78 if (rule) {
79 // XXX It would be better if we can share this with CSSOM tree,
80 // but that may require us to create another map, which is not
81 // great either. As far as they would use the same backend, and
82 // we don't really support mutating @font-face rule via CSSOM,
83 // it's probably fine for now.
84 uint32_t line, column;
85 Servo_FontFaceRule_GetSourceLocation(rule, &line, &column);
86 mRule =
87 new CSSFontFaceRule(do_AddRef(rule), nullptr, nullptr, line, column);
90 return mRule;
93 int32_t InspectorFontFace::SrcIndex() {
94 if (mFontEntry->IsUserFont()) {
95 NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
96 return mFontEntry->mUserFontData->mSrcIndex;
99 return -1;
102 void InspectorFontFace::GetURI(nsAString& aURI) {
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 mFontEntry->mUserFontData->mURI->GetSpec(spec);
109 AppendUTF8toUTF16(spec, aURI);
114 void InspectorFontFace::GetLocalName(nsAString& aLocalName) {
115 aLocalName.Truncate();
116 if (mFontEntry->IsLocalUserFont()) {
117 NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
118 aLocalName.Append(
119 NS_ConvertUTF8toUTF16(mFontEntry->mUserFontData->mLocalName));
123 void InspectorFontFace::GetFormat(nsAString& aFormat) {
124 aFormat.Truncate();
125 if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
126 NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
127 switch (mFontEntry->mUserFontData->mFormatHint) {
128 case StyleFontFaceSourceFormatKeyword::None:
129 break;
130 case StyleFontFaceSourceFormatKeyword::Collection:
131 aFormat.AssignLiteral("collection");
132 break;
133 case StyleFontFaceSourceFormatKeyword::Opentype:
134 aFormat.AssignLiteral("opentype");
135 break;
136 case StyleFontFaceSourceFormatKeyword::Truetype:
137 aFormat.AssignLiteral("truetype");
138 break;
139 case StyleFontFaceSourceFormatKeyword::EmbeddedOpentype:
140 aFormat.AssignLiteral("embedded-opentype");
141 break;
142 case StyleFontFaceSourceFormatKeyword::Svg:
143 aFormat.AssignLiteral("svg");
144 break;
145 case StyleFontFaceSourceFormatKeyword::Woff:
146 aFormat.AssignLiteral("woff");
147 break;
148 case StyleFontFaceSourceFormatKeyword::Woff2:
149 aFormat.AssignLiteral("woff2");
150 break;
151 case StyleFontFaceSourceFormatKeyword::Unknown:
152 aFormat.AssignLiteral("unknown!");
153 break;
158 void InspectorFontFace::GetMetadata(nsAString& aMetadata) {
159 aMetadata.Truncate();
160 if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
161 NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
162 const gfxUserFontData* userFontData = mFontEntry->mUserFontData.get();
163 if (userFontData->mMetadata.Length() && userFontData->mMetaOrigLen) {
164 nsAutoCString str;
165 str.SetLength(userFontData->mMetaOrigLen);
166 if (str.Length() == userFontData->mMetaOrigLen) {
167 switch (userFontData->mCompression) {
168 case gfxUserFontData::kZlibCompression: {
169 uLongf destLen = userFontData->mMetaOrigLen;
170 if (uncompress((Bytef*)(str.BeginWriting()), &destLen,
171 (const Bytef*)(userFontData->mMetadata.Elements()),
172 userFontData->mMetadata.Length()) == Z_OK &&
173 destLen == userFontData->mMetaOrigLen) {
174 AppendUTF8toUTF16(str, aMetadata);
176 } break;
177 case gfxUserFontData::kBrotliCompression: {
178 size_t decodedSize = userFontData->mMetaOrigLen;
179 if (BrotliDecoderDecompress(userFontData->mMetadata.Length(),
180 userFontData->mMetadata.Elements(),
181 &decodedSize,
182 (uint8_t*)str.BeginWriting()) == 1 &&
183 decodedSize == userFontData->mMetaOrigLen) {
184 AppendUTF8toUTF16(str, aMetadata);
186 } break;
193 // Append an OpenType tag to a string as a 4-ASCII-character code.
194 static void AppendTagAsASCII(nsAString& aString, uint32_t aTag) {
195 aString.AppendPrintf("%c%c%c%c", (aTag >> 24) & 0xff, (aTag >> 16) & 0xff,
196 (aTag >> 8) & 0xff, aTag & 0xff);
199 void InspectorFontFace::GetVariationAxes(
200 nsTArray<InspectorVariationAxis>& aResult, ErrorResult& aRV) {
201 if (!mFontEntry->HasVariations()) {
202 return;
204 AutoTArray<gfxFontVariationAxis, 4> axes;
205 mFontEntry->GetVariationAxes(axes);
206 MOZ_ASSERT(!axes.IsEmpty());
207 if (!aResult.SetCapacity(axes.Length(), mozilla::fallible)) {
208 aRV.Throw(NS_ERROR_OUT_OF_MEMORY);
209 return;
211 for (auto a : axes) {
212 InspectorVariationAxis& axis = *aResult.AppendElement();
213 AppendTagAsASCII(axis.mTag, a.mTag);
214 axis.mName.Append(NS_ConvertUTF8toUTF16(a.mName));
215 axis.mMinValue = a.mMinValue;
216 axis.mMaxValue = a.mMaxValue;
217 axis.mDefaultValue = a.mDefaultValue;
221 void InspectorFontFace::GetVariationInstances(
222 nsTArray<InspectorVariationInstance>& aResult, ErrorResult& aRV) {
223 if (!mFontEntry->HasVariations()) {
224 return;
226 AutoTArray<gfxFontVariationInstance, 16> instances;
227 mFontEntry->GetVariationInstances(instances);
228 if (!aResult.SetCapacity(instances.Length(), mozilla::fallible)) {
229 aRV.Throw(NS_ERROR_OUT_OF_MEMORY);
230 return;
232 for (const auto& i : instances) {
233 InspectorVariationInstance& inst = *aResult.AppendElement();
234 inst.mName.Append(NS_ConvertUTF8toUTF16(i.mName));
235 // inst.mValues is a webidl sequence<>, which is a fallible array,
236 // so we are required to use fallible SetCapacity and AppendElement calls,
237 // and check the result. In practice we don't expect failure here; the
238 // list of values cannot get huge because of limits in the font format.
239 if (!inst.mValues.SetCapacity(i.mValues.Length(), mozilla::fallible)) {
240 aRV.Throw(NS_ERROR_OUT_OF_MEMORY);
241 return;
243 for (const auto& v : i.mValues) {
244 InspectorVariationValue value;
245 AppendTagAsASCII(value.mAxis, v.mAxis);
246 value.mValue = v.mValue;
247 // This won't fail, because of SetCapacity above.
248 Unused << inst.mValues.AppendElement(value, mozilla::fallible);
253 void InspectorFontFace::GetFeatures(nsTArray<InspectorFontFeature>& aResult,
254 ErrorResult& aRV) {
255 AutoTArray<gfxFontFeatureInfo, 64> features;
256 mFontEntry->GetFeatureInfo(features);
257 if (features.IsEmpty()) {
258 return;
260 if (!aResult.SetCapacity(features.Length(), mozilla::fallible)) {
261 aRV.Throw(NS_ERROR_OUT_OF_MEMORY);
262 return;
264 for (auto& f : features) {
265 InspectorFontFeature& feat = *aResult.AppendElement();
266 AppendTagAsASCII(feat.mTag, f.mTag);
267 AppendTagAsASCII(feat.mScript, f.mScript);
268 AppendTagAsASCII(feat.mLanguageSystem, f.mLangSys);
272 void InspectorFontFace::GetRanges(nsTArray<RefPtr<nsRange>>& aResult) {
273 aResult = mRanges.Clone();
276 void InspectorFontFace::AddRange(nsRange* aRange) {
277 mRanges.AppendElement(aRange);
280 } // namespace dom
281 } // namespace mozilla