2014-10-01 19:32:05 -07: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-01 19:32:06 -07:00
|
|
|
#include "mozilla/dom/FontFaceSet.h"
|
2014-10-01 19:32:05 -07:00
|
|
|
#include "mozilla/dom/Promise.h"
|
2014-10-01 19:32:06 -07:00
|
|
|
#include "nsCSSRules.h"
|
2014-10-01 19:32:06 -07:00
|
|
|
#include "nsIDocument.h"
|
2014-10-01 19:32:07 -07:00
|
|
|
#include "nsStyleUtil.h"
|
2014-10-01 19:32:05 -07:00
|
|
|
|
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
2014-10-01 19:32:06 -07:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FontFace, mParent, mLoaded, mRule)
|
2014-10-01 19:32:05 -07: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-01 19:32:06 -07:00
|
|
|
FontFace::FontFace(nsISupports* aParent, nsPresContext* aPresContext)
|
2014-10-01 19:32:05 -07:00
|
|
|
: mParent(aParent)
|
2014-10-01 19:32:06 -07:00
|
|
|
, mPresContext(aPresContext)
|
|
|
|
, mStatus(FontFaceLoadStatus::Unloaded)
|
2014-10-01 19:32:05 -07:00
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(FontFace);
|
|
|
|
|
2014-10-01 19:32:06 -07:00
|
|
|
MOZ_ASSERT(mPresContext);
|
|
|
|
|
2014-10-01 19:32:05 -07:00
|
|
|
SetIsDOMBinding();
|
|
|
|
}
|
|
|
|
|
|
|
|
FontFace::~FontFace()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(FontFace);
|
|
|
|
}
|
|
|
|
|
|
|
|
JSObject*
|
|
|
|
FontFace::WrapObject(JSContext* aCx)
|
|
|
|
{
|
|
|
|
return FontFaceBinding::Wrap(aCx, this);
|
|
|
|
}
|
|
|
|
|
2014-10-01 19:32:06 -07: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-01 19:32:06 -07:00
|
|
|
already_AddRefed<FontFace>
|
2014-10-01 19:32:06 -07:00
|
|
|
FontFace::CreateForRule(nsISupports* aGlobal,
|
|
|
|
nsPresContext* aPresContext,
|
|
|
|
nsCSSFontFaceRule* aRule,
|
|
|
|
gfxUserFontEntry* aUserFontEntry)
|
2014-10-01 19:32:06 -07:00
|
|
|
{
|
2014-10-01 19:32:06 -07:00
|
|
|
nsRefPtr<FontFace> obj = new FontFace(aGlobal, aPresContext);
|
2014-10-01 19:32:06 -07:00
|
|
|
obj->mRule = aRule;
|
2014-10-01 19:32:06 -07:00
|
|
|
obj->mStatus = LoadStateToStatus(aUserFontEntry->LoadState());
|
2014-10-01 19:32:06 -07:00
|
|
|
return obj.forget();
|
|
|
|
}
|
|
|
|
|
2014-10-01 19:32:05 -07:00
|
|
|
already_AddRefed<FontFace>
|
|
|
|
FontFace::Constructor(const GlobalObject& aGlobal,
|
|
|
|
const nsAString& aFamily,
|
|
|
|
const StringOrArrayBufferOrArrayBufferView& aSource,
|
|
|
|
const FontFaceDescriptors& aDescriptors,
|
2014-10-01 19:32:06 -07: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-01 19:32:05 -07:00
|
|
|
return obj.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetFamily(nsString& aResult)
|
|
|
|
{
|
2014-10-01 19:32:07 -07: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-01 19:32:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetFamily(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetStyle(nsString& aResult)
|
|
|
|
{
|
2014-10-01 19:32:07 -07:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
GetDesc(eCSSFontDesc_Style, eCSSProperty_font_style, aResult);
|
2014-10-01 19:32:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetStyle(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetWeight(nsString& aResult)
|
|
|
|
{
|
2014-10-01 19:32:07 -07:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
GetDesc(eCSSFontDesc_Weight, eCSSProperty_font_weight, aResult);
|
2014-10-01 19:32:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetWeight(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetStretch(nsString& aResult)
|
|
|
|
{
|
2014-10-01 19:32:07 -07:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
GetDesc(eCSSFontDesc_Stretch, eCSSProperty_font_stretch, aResult);
|
2014-10-01 19:32:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetStretch(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetUnicodeRange(nsString& aResult)
|
|
|
|
{
|
2014-10-01 19:32:07 -07:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
nsCSSValue value;
|
|
|
|
GetDesc(eCSSFontDesc_UnicodeRange, value);
|
|
|
|
|
|
|
|
aResult.Truncate();
|
|
|
|
nsStyleUtil::AppendUnicodeRange(value, aResult);
|
2014-10-01 19:32:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetUnicodeRange(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetVariant(nsString& aResult)
|
|
|
|
{
|
2014-10-01 19:32:07 -07:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
// XXX Just expose the font-variant descriptor as "normal" until we
|
|
|
|
// support it properly (bug 1055385).
|
|
|
|
aResult.AssignLiteral("normal");
|
2014-10-01 19:32:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetVariant(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::GetFeatureSettings(nsString& aResult)
|
|
|
|
{
|
2014-10-01 19:32:07 -07:00
|
|
|
mPresContext->FlushUserFontSet();
|
|
|
|
|
|
|
|
nsCSSValue value;
|
|
|
|
GetDesc(eCSSFontDesc_FontFeatureSettings, value);
|
|
|
|
|
|
|
|
aResult.Truncate();
|
|
|
|
nsStyleUtil::AppendFontFeatureSettings(value, aResult);
|
2014-10-01 19:32:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetFeatureSettings(const nsAString& aValue, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
FontFaceLoadStatus
|
|
|
|
FontFace::Status()
|
|
|
|
{
|
2014-10-01 19:32:06 -07:00
|
|
|
return mStatus;
|
2014-10-01 19:32:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Promise*
|
|
|
|
FontFace::Load()
|
|
|
|
{
|
|
|
|
return Loaded();
|
|
|
|
}
|
|
|
|
|
|
|
|
Promise*
|
|
|
|
FontFace::Loaded()
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
2014-10-01 19:32:06 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
FontFace::SetStatus(FontFaceLoadStatus aStatus)
|
|
|
|
{
|
|
|
|
mStatus = aStatus;
|
|
|
|
}
|
|
|
|
|
2014-10-01 19:32:07 -07: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-01 19:32:06 -07:00
|
|
|
// -- FontFace::Entry --------------------------------------------------------
|
|
|
|
|
|
|
|
/* virtual */ void
|
|
|
|
FontFace::Entry::SetLoadState(UserFontLoadState aLoadState)
|
|
|
|
{
|
|
|
|
gfxUserFontEntry::SetLoadState(aLoadState);
|
|
|
|
|
|
|
|
FontFace* face = GetFontFace();
|
|
|
|
if (face) {
|
|
|
|
face->SetStatus(LoadStateToStatus(aLoadState));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FontFace*
|
|
|
|
FontFace::Entry::GetFontFace()
|
|
|
|
{
|
|
|
|
FontFaceSet* fontFaceSet =
|
|
|
|
static_cast<FontFaceSet::UserFontSet*>(mFontSet)->GetFontFaceSet();
|
|
|
|
if (!fontFaceSet) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fontFaceSet->FindFontFaceForEntry(this);
|
|
|
|
}
|