Mypal/layout/inspector/nsFontFace.cpp

226 lines
6.3 KiB
C++

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsFontFace.h"
#include "nsIDOMCSSFontFaceRule.h"
#include "nsCSSRules.h"
#include "gfxTextRun.h"
#include "gfxUserFontSet.h"
#include "nsFontFaceLoader.h"
#include "mozilla/gfx/2D.h"
#include "brotli/decode.h"
#include "zlib.h"
#include "mozilla/dom/FontFaceSet.h"
using namespace mozilla;
using namespace mozilla::dom;
nsFontFace::nsFontFace(gfxFontEntry* aFontEntry,
gfxFontGroup* aFontGroup,
uint8_t aMatchType)
: mFontEntry(aFontEntry),
mFontGroup(aFontGroup),
mMatchType(aMatchType)
{
}
nsFontFace::~nsFontFace()
{
}
////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS(nsFontFace, nsIDOMFontFace)
////////////////////////////////////////////////////////////////////////
// nsIDOMFontFace
NS_IMETHODIMP
nsFontFace::GetFromFontGroup(bool * aFromFontGroup)
{
*aFromFontGroup =
(mMatchType & gfxTextRange::kFontGroup) != 0;
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetFromLanguagePrefs(bool * aFromLanguagePrefs)
{
*aFromLanguagePrefs =
(mMatchType & gfxTextRange::kPrefsFallback) != 0;
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetFromSystemFallback(bool * aFromSystemFallback)
{
*aFromSystemFallback =
(mMatchType & gfxTextRange::kSystemFallback) != 0;
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetName(nsAString & aName)
{
if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
aName = mFontEntry->mUserFontData->mRealName;
} else {
aName = mFontEntry->RealFaceName();
}
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetCSSFamilyName(nsAString & aCSSFamilyName)
{
aCSSFamilyName = mFontEntry->FamilyName();
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetRule(nsIDOMCSSFontFaceRule **aRule)
{
// check whether this font entry is associated with an @font-face rule
// in the relevant font group's user font set
nsCSSFontFaceRule* rule = nullptr;
if (mFontEntry->IsUserFont()) {
FontFaceSet::UserFontSet* fontSet =
static_cast<FontFaceSet::UserFontSet*>(mFontGroup->GetUserFontSet());
if (fontSet) {
FontFaceSet* fontFaceSet = fontSet->GetFontFaceSet();
if (fontFaceSet) {
rule = fontFaceSet->FindRuleForEntry(mFontEntry);
}
}
}
NS_IF_ADDREF(*aRule = rule);
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetSrcIndex(int32_t * aSrcIndex)
{
if (mFontEntry->IsUserFont()) {
NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
*aSrcIndex = mFontEntry->mUserFontData->mSrcIndex;
} else {
*aSrcIndex = -1;
}
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetURI(nsAString & aURI)
{
aURI.Truncate();
if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
if (mFontEntry->mUserFontData->mURI) {
nsAutoCString spec;
nsresult rv = mFontEntry->mUserFontData->mURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
AppendUTF8toUTF16(spec, aURI);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetLocalName(nsAString & aLocalName)
{
if (mFontEntry->IsLocalUserFont()) {
NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
aLocalName = mFontEntry->mUserFontData->mLocalName;
} else {
aLocalName.Truncate();
}
return NS_OK;
}
static void
AppendToFormat(nsAString & aResult, const char* aFormat)
{
if (!aResult.IsEmpty()) {
aResult.Append(',');
}
aResult.AppendASCII(aFormat);
}
NS_IMETHODIMP
nsFontFace::GetFormat(nsAString & aFormat)
{
aFormat.Truncate();
if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
uint32_t formatFlags = mFontEntry->mUserFontData->mFormat;
if (formatFlags & gfxUserFontSet::FLAG_FORMAT_OPENTYPE) {
AppendToFormat(aFormat, "opentype");
}
if (formatFlags & gfxUserFontSet::FLAG_FORMAT_TRUETYPE) {
AppendToFormat(aFormat, "truetype");
}
if (formatFlags & gfxUserFontSet::FLAG_FORMAT_TRUETYPE_AAT) {
AppendToFormat(aFormat, "truetype-aat");
}
if (formatFlags & gfxUserFontSet::FLAG_FORMAT_EOT) {
AppendToFormat(aFormat, "embedded-opentype");
}
if (formatFlags & gfxUserFontSet::FLAG_FORMAT_SVG) {
AppendToFormat(aFormat, "svg");
}
if (formatFlags & gfxUserFontSet::FLAG_FORMAT_WOFF) {
AppendToFormat(aFormat, "woff");
}
if (formatFlags & gfxUserFontSet::FLAG_FORMAT_WOFF2) {
AppendToFormat(aFormat, "woff2");
}
}
return NS_OK;
}
NS_IMETHODIMP
nsFontFace::GetMetadata(nsAString & aMetadata)
{
aMetadata.Truncate();
if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
const gfxUserFontData* userFontData = mFontEntry->mUserFontData.get();
if (userFontData->mMetadata.Length() && userFontData->mMetaOrigLen) {
nsAutoCString str;
str.SetLength(userFontData->mMetaOrigLen);
if (str.Length() == userFontData->mMetaOrigLen) {
switch (userFontData->mCompression) {
case gfxUserFontData::kZlibCompression:
{
uLongf destLen = userFontData->mMetaOrigLen;
if (uncompress((Bytef *)(str.BeginWriting()), &destLen,
(const Bytef *)(userFontData->mMetadata.Elements()),
userFontData->mMetadata.Length()) == Z_OK &&
destLen == userFontData->mMetaOrigLen) {
AppendUTF8toUTF16(str, aMetadata);
}
}
break;
case gfxUserFontData::kBrotliCompression:
{
size_t decodedSize = userFontData->mMetaOrigLen;
if (BrotliDecoderDecompress(userFontData->mMetadata.Length(),
userFontData->mMetadata.Elements(),
&decodedSize,
(uint8_t*)str.BeginWriting()) == 1 &&
decodedSize == userFontData->mMetaOrigLen) {
AppendUTF8toUTF16(str, aMetadata);
}
}
break;
}
}
}
}
return NS_OK;
}