2014-10-02 06:32:05 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* 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 "mozilla/dom/FontFace.h"
|
|
|
|
|
|
|
|
#include "mozilla/dom/FontFaceBinding.h"
|
2014-10-02 06:32:06 +04:00
|
|
|
#include "mozilla/dom/FontFaceSet.h"
|
2014-10-02 06:32:05 +04:00
|
|
|
#include "mozilla/dom/Promise.h"
|
2014-10-02 06:32:07 +04:00
|
|
|
#include "nsCSSParser.h"
|
2014-10-02 06:32:06 +04:00
|
|
|
#include "nsCSSRules.h"
|
2014-10-02 06:32:06 +04:00
|
|
|
#include "nsIDocument.h"
|
2014-10-02 06:32:07 +04:00
|
|
|
#include "nsStyleUtil.h"
|
2014-10-02 06:32:05 +04:00
|
|
|
|
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
2014-10-02 06:32:08 +04:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(FontFace)
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FontFace)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoaded)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRule)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFontFaceSet)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FontFace)
|
|
|
|
if (!tmp->IsInFontFaceSet()) {
|
|
|
|
tmp->mFontFaceSet->RemoveUnavailableFontFace(tmp);
|
|
|
|
}
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoaded)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRule)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFontFaceSet)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(FontFace)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
2014-10-02 06:32:05 +04:00
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FontFace)
|
|
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(FontFace)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(FontFace)
|
|
|
|
|
2014-10-02 06:32:06 +04:00
|
|
|
FontFace::FontFace(nsISupports* aParent, nsPresContext* aPresContext)
|
2014-10-02 06:32:05 +04:00
|
|
|
: mParent(aParent)
|
2014-10-02 06:32:06 +04:00
|
|
|
, mPresContext(aPresContext)
|
|
|
|
, mStatus(FontFaceLoadStatus::Unloaded)
|
2014-10-02 06:32:08 +04:00
|
|
|
, mFontFaceSet(aPresContext->Fonts())
|
|
|
|
, mInFontFaceSet(false)
|
2014-10-02 06:32:05 +04:00
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(FontFace);
|
|
|
|
|
|
|
|
SetIsDOMBinding();
|
2014-10-02 06:32:07 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aParent);
|
|
|
|
|
|
|
|
if (global) {
|
|
|
|
ErrorResult rv;
|
|
|
|
mLoaded = Promise::Create(global, rv);
|
|
|
|
}
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
FontFace::~FontFace()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(FontFace);
|
2014-10-02 06:32:08 +04:00
|
|
|
|
|
|
|
SetUserFontEntry(nullptr);
|
2014-10-02 06:32:08 +04:00
|
|
|
|
|
|
|
if (mFontFaceSet && !IsInFontFaceSet()) {
|
|
|
|
mFontFaceSet->RemoveUnavailableFontFace(this);
|
|
|
|
}
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
JSObject*
|
|
|
|
FontFace::WrapObject(JSContext* aCx)
|
|
|
|
{
|
|
|
|
return FontFaceBinding::Wrap(aCx, this);
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:06 +04:00
|
|
|
static FontFaceLoadStatus
|
|
|
|
LoadStateToStatus(gfxUserFontEntry::UserFontLoadState aLoadState)
|
|
|
|
{
|
|
|
|
switch (aLoadState) {
|
|
|
|
case gfxUserFontEntry::UserFontLoadState::STATUS_NOT_LOADED:
|
|
|
|
return FontFaceLoadStatus::Unloaded;
|
|
|
|
case gfxUserFontEntry::UserFontLoadState::STATUS_LOADING:
|
|
|
|
return FontFaceLoadStatus::Loading;
|
|
|
|
case gfxUserFontEntry::UserFontLoadState::STATUS_LOADED:
|
|
|
|
return FontFaceLoadStatus::Loaded;
|
|
|
|
case gfxUserFontEntry::UserFontLoadState::STATUS_FAILED:
|
|
|
|
return FontFaceLoadStatus::Error;
|
|
|
|
}
|
|
|
|
NS_NOTREACHED("invalid aLoadState value");
|
|
|
|
return FontFaceLoadStatus::Error;
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:06 +04:00
|
|
|
already_AddRefed<FontFace>
|
2014-10-02 06:32:06 +04:00
|
|
|
FontFace::CreateForRule(nsISupports* aGlobal,
|
|
|
|
nsPresContext* aPresContext,
|
|
|
|
nsCSSFontFaceRule* aRule,
|
|
|
|
gfxUserFontEntry* aUserFontEntry)
|
2014-10-02 06:32:06 +04:00
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(aGlobal);
|
|
|
|
|
2014-10-02 06:32:06 +04:00
|
|
|
nsRefPtr<FontFace> obj = new FontFace(aGlobal, aPresContext);
|
2014-10-02 06:32:06 +04:00
|
|
|
obj->mRule = aRule;
|
2014-10-02 06:32:08 +04:00
|
|
|
obj->mInFontFaceSet = true;
|
2014-10-02 06:32:08 +04:00
|
|
|
obj->SetUserFontEntry(aUserFontEntry);
|
2014-10-02 06:32:06 +04:00
|
|
|
return obj.forget();
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:05 +04:00
|
|
|
already_AddRefed<FontFace>
|
|
|
|
FontFace::Constructor(const GlobalObject& aGlobal,
|
|
|
|
const nsAString& aFamily,
|
|
|
|
const StringOrArrayBufferOrArrayBufferView& aSource,
|
|
|
|
const FontFaceDescriptors& aDescriptors,
|
2014-10-02 06:32:06 +04:00
|
|
|
ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
nsISupports* global = aGlobal.GetAsSupports();
|
|
|
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global);
|
|
|
|
nsIDocument* doc = window->GetDoc();
|
|
|
|
if (!doc) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIPresShell* shell = doc->GetShell();
|
|
|
|
if (!shell) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPresContext* presContext = shell->GetPresContext();
|
|
|
|
if (!presContext) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsRefPtr<FontFace> obj = new FontFace(global, presContext);
|
2014-10-02 06:32:08 +04:00
|
|
|
obj->mFontFaceSet->AddUnavailableFontFace(obj);
|
2014-10-02 06:32:05 +04:00
|
|
|
return obj.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetFamily(nsString& aResult)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
// Serialize the same way as in nsCSSFontFaceStyleDecl::GetPropertyValue.
|
|
|
|
nsCSSValue value;
|
|
|
|
GetDesc(eCSSFontDesc_Family, value);
|
|
|
|
|
|
|
|
aResult.Truncate();
|
|
|
|
nsDependentString family(value.GetStringBufferValue());
|
|
|
|
nsStyleUtil::AppendEscapedCSSString(family, aResult);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetFamily(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
SetDescriptor(eCSSFontDesc_Family, aValue, aRv);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetStyle(nsString& aResult)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
GetDesc(eCSSFontDesc_Style, eCSSProperty_font_style, aResult);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetStyle(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
SetDescriptor(eCSSFontDesc_Style, aValue, aRv);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetWeight(nsString& aResult)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
GetDesc(eCSSFontDesc_Weight, eCSSProperty_font_weight, aResult);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetWeight(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
SetDescriptor(eCSSFontDesc_Weight, aValue, aRv);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetStretch(nsString& aResult)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
GetDesc(eCSSFontDesc_Stretch, eCSSProperty_font_stretch, aResult);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetStretch(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
SetDescriptor(eCSSFontDesc_Stretch, aValue, aRv);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetUnicodeRange(nsString& aResult)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
nsCSSValue value;
|
|
|
|
GetDesc(eCSSFontDesc_UnicodeRange, value);
|
|
|
|
|
|
|
|
aResult.Truncate();
|
|
|
|
nsStyleUtil::AppendUnicodeRange(value, aResult);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetUnicodeRange(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
SetDescriptor(eCSSFontDesc_UnicodeRange, aValue, aRv);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetVariant(nsString& aResult)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
// XXX Just expose the font-variant descriptor as "normal" until we
|
|
|
|
// support it properly (bug 1055385).
|
|
|
|
aResult.AssignLiteral("normal");
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetVariant(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
// XXX Ignore assignments to variant until we support font-variant
|
|
|
|
// descriptors (bug 1055385).
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetFeatureSettings(nsString& aResult)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
nsCSSValue value;
|
|
|
|
GetDesc(eCSSFontDesc_FontFeatureSettings, value);
|
|
|
|
|
|
|
|
aResult.Truncate();
|
|
|
|
nsStyleUtil::AppendFontFeatureSettings(value, aResult);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetFeatureSettings(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
SetDescriptor(eCSSFontDesc_FontFeatureSettings, aValue, aRv);
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
FontFaceLoadStatus
|
|
|
|
FontFace::Status()
|
|
|
|
{
|
2014-10-02 06:32:06 +04:00
|
|
|
return mStatus;
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Promise*
|
2014-10-02 06:32:07 +04:00
|
|
|
FontFace::Load(ErrorResult& aRv)
|
2014-10-02 06:32:05 +04:00
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
2014-10-02 06:32:07 +04:00
|
|
|
if (!mLoaded) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:07 +04:00
|
|
|
if (mStatus != FontFaceLoadStatus::Unloaded) {
|
|
|
|
return mLoaded;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetStatus(FontFaceLoadStatus::Loading);
|
|
|
|
|
2014-10-02 06:32:08 +04:00
|
|
|
mUserFontEntry->Load();
|
2014-10-02 06:32:07 +04:00
|
|
|
return mLoaded;
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Promise*
|
2014-10-02 06:32:07 +04:00
|
|
|
FontFace::GetLoaded(ErrorResult& aRv)
|
2014-10-02 06:32:05 +04:00
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
if (!mLoaded) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mLoaded;
|
2014-10-02 06:32:05 +04:00
|
|
|
}
|
2014-10-02 06:32:06 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetStatus(FontFaceLoadStatus aStatus)
|
|
|
|
{
|
2014-10-02 06:32:07 +04:00
|
|
|
if (mStatus == aStatus) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:08 +04:00
|
|
|
if (aStatus < mStatus) {
|
|
|
|
// We're being asked to go backwards in status! Normally, this shouldn't
|
|
|
|
// happen. But it can if the FontFace had a user font entry that had
|
|
|
|
// loaded, but then was given a new one by FontFaceSet::InsertRuleFontFace
|
|
|
|
// if we used a local() rule. For now, just ignore the request to
|
|
|
|
// go backwards in status.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:06 +04:00
|
|
|
mStatus = aStatus;
|
2014-10-02 06:32:07 +04:00
|
|
|
|
|
|
|
if (!mLoaded) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mStatus == FontFaceLoadStatus::Loaded) {
|
|
|
|
mLoaded->MaybeResolve(this);
|
|
|
|
} else if (mStatus == FontFaceLoadStatus::Error) {
|
|
|
|
// XXX Use NS_ERROR_DOM_SYNTAX_ERR for array buffer backed FontFaces.
|
|
|
|
mLoaded->MaybeReject(NS_ERROR_DOM_NETWORK_ERR);
|
|
|
|
}
|
2014-10-02 06:32:06 +04:00
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:07 +04:00
|
|
|
bool
|
|
|
|
FontFace::ParseDescriptor(nsCSSFontDesc aDescID,
|
|
|
|
const nsAString& aString,
|
|
|
|
nsCSSValue& aResult)
|
|
|
|
{
|
|
|
|
nsCSSParser parser;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mParent);
|
|
|
|
nsCOMPtr<nsIPrincipal> principal = global->PrincipalOrNull();
|
|
|
|
|
|
|
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mParent);
|
|
|
|
nsCOMPtr<nsIURI> base = window->GetDocBaseURI();
|
|
|
|
|
|
|
|
if (!parser.ParseFontFaceDescriptor(aDescID, aString,
|
|
|
|
nullptr, // aSheetURL
|
|
|
|
base,
|
|
|
|
principal,
|
|
|
|
aResult)) {
|
|
|
|
aResult.Reset();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetDescriptor(nsCSSFontDesc aFontDesc,
|
|
|
|
const nsAString& aValue,
|
|
|
|
ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(!mRule, "we don't handle rule-connected FontFace objects yet");
|
|
|
|
if (mRule) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCSSValue parsedValue;
|
|
|
|
if (!ParseDescriptor(aFontDesc, aValue, parsedValue)) {
|
|
|
|
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mDescriptors->Get(aFontDesc) = parsedValue;
|
|
|
|
|
|
|
|
// XXX Setting descriptors doesn't actually have any effect on FontFace
|
|
|
|
// objects that have started loading or have already been loaded.
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:07 +04:00
|
|
|
void
|
|
|
|
FontFace::GetDesc(nsCSSFontDesc aDescID, nsCSSValue& aResult) const
|
|
|
|
{
|
|
|
|
if (mRule) {
|
|
|
|
MOZ_ASSERT(!mDescriptors);
|
|
|
|
mRule->GetDesc(aDescID, aResult);
|
|
|
|
} else {
|
|
|
|
aResult = mDescriptors->Get(aDescID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetDesc(nsCSSFontDesc aDescID,
|
|
|
|
nsCSSProperty aPropID,
|
|
|
|
nsString& aResult) const
|
|
|
|
{
|
|
|
|
nsCSSValue value;
|
|
|
|
GetDesc(aDescID, value);
|
|
|
|
|
|
|
|
aResult.Truncate();
|
|
|
|
|
|
|
|
// Fill in a default value for missing descriptors.
|
|
|
|
if (value.GetUnit() == eCSSUnit_Null) {
|
|
|
|
if (aDescID == eCSSFontDesc_UnicodeRange) {
|
|
|
|
aResult.AssignLiteral("U+0-10FFFF");
|
|
|
|
} else if (aDescID != eCSSFontDesc_Family &&
|
|
|
|
aDescID != eCSSFontDesc_Src) {
|
|
|
|
aResult.AssignLiteral("normal");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
value.AppendToString(aPropID, aResult, nsCSSValue::eNormalized);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:08 +04:00
|
|
|
void
|
|
|
|
FontFace::SetUserFontEntry(gfxUserFontEntry* aEntry)
|
|
|
|
{
|
|
|
|
if (mUserFontEntry) {
|
|
|
|
mUserFontEntry->mFontFaces.RemoveElement(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
mUserFontEntry = static_cast<Entry*>(aEntry);
|
|
|
|
if (mUserFontEntry) {
|
|
|
|
mUserFontEntry->mFontFaces.AppendElement(this);
|
|
|
|
|
|
|
|
// Our newly assigned user font entry might be in the process of or
|
|
|
|
// finished loading, so set our status accordingly. But only do so
|
|
|
|
// if we're not going "backwards" in status, which could otherwise
|
|
|
|
// happen in this case:
|
|
|
|
//
|
|
|
|
// new FontFace("ABC", "url(x)").load();
|
|
|
|
//
|
|
|
|
// where the SetUserFontEntry call (from the after-initialization
|
|
|
|
// FontFaceSet::LoadFontFace call) comes after the author's call to
|
|
|
|
// load(), which set mStatus to Loading.
|
|
|
|
FontFaceLoadStatus newStatus =
|
|
|
|
LoadStateToStatus(mUserFontEntry->LoadState());
|
|
|
|
if (newStatus > mStatus) {
|
|
|
|
SetStatus(newStatus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:08 +04:00
|
|
|
bool
|
|
|
|
FontFace::GetFamilyName(nsString& aResult)
|
|
|
|
{
|
|
|
|
nsCSSValue value;
|
|
|
|
GetDesc(eCSSFontDesc_Family, value);
|
|
|
|
|
|
|
|
if (value.GetUnit() == eCSSUnit_String) {
|
|
|
|
nsString familyname;
|
|
|
|
value.GetStringValue(familyname);
|
|
|
|
aResult.Append(familyname);
|
|
|
|
}
|
|
|
|
|
|
|
|
return !aResult.IsEmpty();
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:08 +04:00
|
|
|
void
|
|
|
|
FontFace::DisconnectFromRule()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsConnected());
|
|
|
|
|
|
|
|
// Make a copy of the descriptors.
|
|
|
|
mDescriptors = new CSSFontFaceDescriptors;
|
|
|
|
mRule->GetDescriptors(*mDescriptors);
|
|
|
|
|
|
|
|
mRule->SetFontFace(nullptr);
|
|
|
|
mRule = nullptr;
|
|
|
|
mInFontFaceSet = false;
|
|
|
|
}
|
|
|
|
|
2014-10-02 06:32:06 +04:00
|
|
|
// -- FontFace::Entry --------------------------------------------------------
|
|
|
|
|
|
|
|
/* virtual */ void
|
|
|
|
FontFace::Entry::SetLoadState(UserFontLoadState aLoadState)
|
|
|
|
{
|
|
|
|
gfxUserFontEntry::SetLoadState(aLoadState);
|
|
|
|
|
2014-10-02 06:32:08 +04:00
|
|
|
for (size_t i = 0; i < mFontFaces.Length(); i++) {
|
|
|
|
mFontFaces[i]->SetStatus(LoadStateToStatus(aLoadState));
|
2014-10-02 06:32:06 +04:00
|
|
|
}
|
|
|
|
}
|