mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 906643. Part 7: Hook up animation support for gfxSVGGlyphs. r=jfkthame
There's a few things mashed together in this patch: -- Enable animations in glyph documents -- Make gfxSVGGlyphsDocument monitor the document's refresh driver to detect updates -- Forward updates to the gfxFontEntry
This commit is contained in:
parent
4e461c3ef8
commit
82ad22f4ba
@ -89,6 +89,61 @@ gfxCharacterMap::NotifyReleased()
|
||||
delete this;
|
||||
}
|
||||
|
||||
gfxFontEntry::gfxFontEntry() :
|
||||
mItalic(false), mFixedPitch(false),
|
||||
mIsProxy(false), mIsValid(true),
|
||||
mIsBadUnderlineFont(false),
|
||||
mIsUserFont(false),
|
||||
mIsLocalUserFont(false),
|
||||
mStandardFace(false),
|
||||
mSymbolFont(false),
|
||||
mIgnoreGDEF(false),
|
||||
mIgnoreGSUB(false),
|
||||
mSVGInitialized(false),
|
||||
mHasSpaceFeaturesInitialized(false),
|
||||
mHasSpaceFeatures(false),
|
||||
mHasSpaceFeaturesKerning(false),
|
||||
mHasSpaceFeaturesNonKerning(false),
|
||||
mHasSpaceFeaturesSubDefault(false),
|
||||
mCheckedForGraphiteTables(false),
|
||||
mHasCmapTable(false),
|
||||
mGrFaceInitialized(false),
|
||||
mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
|
||||
mUVSOffset(0), mUVSData(nullptr),
|
||||
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
mHBFace(nullptr),
|
||||
mGrFace(nullptr),
|
||||
mGrFaceRefCnt(0)
|
||||
{
|
||||
}
|
||||
|
||||
gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) :
|
||||
mName(aName), mItalic(false), mFixedPitch(false),
|
||||
mIsProxy(false), mIsValid(true),
|
||||
mIsBadUnderlineFont(false), mIsUserFont(false),
|
||||
mIsLocalUserFont(false), mStandardFace(aIsStandardFace),
|
||||
mSymbolFont(false),
|
||||
mIgnoreGDEF(false),
|
||||
mIgnoreGSUB(false),
|
||||
mSVGInitialized(false),
|
||||
mHasSpaceFeaturesInitialized(false),
|
||||
mHasSpaceFeatures(false),
|
||||
mHasSpaceFeaturesKerning(false),
|
||||
mHasSpaceFeaturesNonKerning(false),
|
||||
mHasSpaceFeaturesSubDefault(false),
|
||||
mCheckedForGraphiteTables(false),
|
||||
mHasCmapTable(false),
|
||||
mGrFaceInitialized(false),
|
||||
mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
|
||||
mUVSOffset(0), mUVSData(nullptr),
|
||||
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
mHBFace(nullptr),
|
||||
mGrFace(nullptr),
|
||||
mGrFaceRefCnt(0)
|
||||
{
|
||||
memset(&mHasSpaceFeaturesSub, 0, sizeof(mHasSpaceFeaturesSub));
|
||||
}
|
||||
|
||||
gfxFontEntry::~gfxFontEntry()
|
||||
{
|
||||
// For downloaded fonts, we need to tell the user font cache that this
|
||||
@ -102,11 +157,6 @@ gfxFontEntry::~gfxFontEntry()
|
||||
// face objects should have been released.
|
||||
MOZ_ASSERT(!mHBFace);
|
||||
MOZ_ASSERT(!mGrFaceInitialized);
|
||||
|
||||
if (mSVGGlyphs) {
|
||||
delete mSVGGlyphs;
|
||||
}
|
||||
delete mUserFontData;
|
||||
}
|
||||
|
||||
bool gfxFontEntry::IsSymbolFont()
|
||||
@ -266,7 +316,7 @@ gfxFontEntry::TryGetSVGData(gfxFont* aFont)
|
||||
|
||||
// gfxSVGGlyphs will hb_blob_destroy() the table when it is finished
|
||||
// with it.
|
||||
mSVGGlyphs = new gfxSVGGlyphs(svgTable);
|
||||
mSVGGlyphs = new gfxSVGGlyphs(svgTable, this);
|
||||
}
|
||||
|
||||
if (!mFontsUsingSVGGlyphs.Contains(aFont)) {
|
||||
|
@ -228,35 +228,7 @@ class gfxFontEntry {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(gfxFontEntry)
|
||||
|
||||
gfxFontEntry(const nsAString& aName, bool aIsStandardFace = false) :
|
||||
mName(aName), mItalic(false), mFixedPitch(false),
|
||||
mIsProxy(false), mIsValid(true),
|
||||
mIsBadUnderlineFont(false), mIsUserFont(false),
|
||||
mIsLocalUserFont(false), mStandardFace(aIsStandardFace),
|
||||
mSymbolFont(false),
|
||||
mIgnoreGDEF(false),
|
||||
mIgnoreGSUB(false),
|
||||
mSVGInitialized(false),
|
||||
mHasSpaceFeaturesInitialized(false),
|
||||
mHasSpaceFeatures(false),
|
||||
mHasSpaceFeaturesKerning(false),
|
||||
mHasSpaceFeaturesNonKerning(false),
|
||||
mHasSpaceFeaturesSubDefault(false),
|
||||
mCheckedForGraphiteTables(false),
|
||||
mHasCmapTable(false),
|
||||
mGrFaceInitialized(false),
|
||||
mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
|
||||
mUVSOffset(0), mUVSData(nullptr),
|
||||
mUserFontData(nullptr),
|
||||
mSVGGlyphs(nullptr),
|
||||
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
mHBFace(nullptr),
|
||||
mGrFace(nullptr),
|
||||
mGrFaceRefCnt(0)
|
||||
{
|
||||
memset(&mHasSpaceFeaturesSub, 0, sizeof(mHasSpaceFeaturesSub));
|
||||
}
|
||||
|
||||
gfxFontEntry(const nsAString& aName, bool aIsStandardFace = false);
|
||||
virtual ~gfxFontEntry();
|
||||
|
||||
// unique name for the face, *not* the family; not necessarily the
|
||||
@ -462,8 +434,8 @@ public:
|
||||
nsRefPtr<gfxCharacterMap> mCharacterMap;
|
||||
uint32_t mUVSOffset;
|
||||
nsAutoArrayPtr<uint8_t> mUVSData;
|
||||
gfxUserFontData* mUserFontData;
|
||||
gfxSVGGlyphs *mSVGGlyphs;
|
||||
nsAutoPtr<gfxUserFontData> mUserFontData;
|
||||
nsAutoPtr<gfxSVGGlyphs> mSVGGlyphs;
|
||||
// list of gfxFonts that are using SVG glyphs
|
||||
nsTArray<gfxFont*> mFontsUsingSVGGlyphs;
|
||||
nsTArray<gfxFontFeature> mFeatureSettings;
|
||||
@ -476,34 +448,7 @@ protected:
|
||||
friend class gfxFontFamily;
|
||||
friend class gfxSingleFaceMacFontFamily;
|
||||
|
||||
gfxFontEntry() :
|
||||
mItalic(false), mFixedPitch(false),
|
||||
mIsProxy(false), mIsValid(true),
|
||||
mIsBadUnderlineFont(false),
|
||||
mIsUserFont(false),
|
||||
mIsLocalUserFont(false),
|
||||
mStandardFace(false),
|
||||
mSymbolFont(false),
|
||||
mIgnoreGDEF(false),
|
||||
mIgnoreGSUB(false),
|
||||
mSVGInitialized(false),
|
||||
mHasSpaceFeaturesInitialized(false),
|
||||
mHasSpaceFeatures(false),
|
||||
mHasSpaceFeaturesKerning(false),
|
||||
mHasSpaceFeaturesNonKerning(false),
|
||||
mHasSpaceFeaturesSubDefault(false),
|
||||
mCheckedForGraphiteTables(false),
|
||||
mHasCmapTable(false),
|
||||
mGrFaceInitialized(false),
|
||||
mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
|
||||
mUVSOffset(0), mUVSData(nullptr),
|
||||
mUserFontData(nullptr),
|
||||
mSVGGlyphs(nullptr),
|
||||
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
mHBFace(nullptr),
|
||||
mGrFace(nullptr),
|
||||
mGrFaceRefCnt(0)
|
||||
{ }
|
||||
gfxFontEntry();
|
||||
|
||||
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold) {
|
||||
NS_NOTREACHED("oops, somebody didn't override CreateFontInstance");
|
||||
|
@ -31,11 +31,15 @@
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "gfxFont.h"
|
||||
#include "nsSMILAnimationController.h"
|
||||
#include "harfbuzz/hb.h"
|
||||
|
||||
#define SVG_CONTENT_TYPE NS_LITERAL_CSTRING("image/svg+xml")
|
||||
#define UTF8_CHARSET NS_LITERAL_CSTRING("utf-8")
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
typedef mozilla::dom::Element Element;
|
||||
|
||||
mozilla::gfx::UserDataKey gfxTextContextPaint::sUserDataKey;
|
||||
@ -44,10 +48,10 @@ const float gfxSVGGlyphs::SVG_UNITS_PER_EM = 1000.0f;
|
||||
|
||||
const gfxRGBA SimpleTextContextPaint::sZero = gfxRGBA(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
gfxSVGGlyphs::gfxSVGGlyphs(hb_blob_t *aSVGTable)
|
||||
gfxSVGGlyphs::gfxSVGGlyphs(hb_blob_t *aSVGTable, gfxFontEntry *aFontEntry)
|
||||
: mSVGData(aSVGTable)
|
||||
, mFontEntry(aFontEntry)
|
||||
{
|
||||
mSVGData = aSVGTable;
|
||||
|
||||
unsigned int length;
|
||||
const char* svgData = hb_blob_get_data(mSVGData, &length);
|
||||
mHeader = reinterpret_cast<const Header*>(svgData);
|
||||
@ -70,6 +74,12 @@ gfxSVGGlyphs::~gfxSVGGlyphs()
|
||||
hb_blob_destroy(mSVGData);
|
||||
}
|
||||
|
||||
void
|
||||
gfxSVGGlyphs::DidRefresh()
|
||||
{
|
||||
mFontEntry->NotifyGlyphsChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
* Comparison operator for finding a range containing a given glyph ID. Simply
|
||||
* checks whether |key| is less (greater) than every element of |range|, in
|
||||
@ -120,7 +130,7 @@ gfxSVGGlyphs::FindOrCreateGlyphsDocument(uint32_t aGlyphId)
|
||||
if (entry->mDocOffset > 0 &&
|
||||
uint64_t(mHeader->mDocIndexOffset) + entry->mDocOffset + entry->mDocLength <= length) {
|
||||
result = new gfxSVGGlyphsDocument(data + mHeader->mDocIndexOffset + entry->mDocOffset,
|
||||
entry->mDocLength);
|
||||
entry->mDocLength, this);
|
||||
mGlyphDocs.Put(entry->mDocOffset, result);
|
||||
}
|
||||
}
|
||||
@ -131,8 +141,6 @@ gfxSVGGlyphs::FindOrCreateGlyphsDocument(uint32_t aGlyphId)
|
||||
nsresult
|
||||
gfxSVGGlyphsDocument::SetupPresentation()
|
||||
{
|
||||
mDocument->SetIsBeingUsedAsImage();
|
||||
|
||||
nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
|
||||
nsXPIDLCString contractId;
|
||||
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "image/svg+xml", getter_Copies(contractId));
|
||||
@ -154,22 +162,36 @@ gfxSVGGlyphsDocument::SetupPresentation()
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
rv = viewer->GetPresShell(getter_AddRefs(presShell));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
presShell->GetPresContext()->SetIsGlyph(true);
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
presContext->SetIsGlyph(true);
|
||||
|
||||
if (!presShell->DidInitialize()) {
|
||||
nsRect rect = presShell->GetPresContext()->GetVisibleArea();
|
||||
nsRect rect = presContext->GetVisibleArea();
|
||||
rv = presShell->Initialize(rect.width, rect.height);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mDocument->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
nsSMILAnimationController* controller = mDocument->GetAnimationController();
|
||||
if (controller) {
|
||||
controller->Resume(nsSMILTimeContainer::PAUSE_IMAGE);
|
||||
}
|
||||
mDocument->SetImagesNeedAnimating(true);
|
||||
|
||||
mViewer = viewer;
|
||||
mPresShell = presShell;
|
||||
mPresShell->AddPostRefreshObserver(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
gfxSVGGlyphsDocument::DidRefresh()
|
||||
{
|
||||
mOwner->DidRefresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk the DOM tree to find all glyph elements and insert them into the lookup
|
||||
* table
|
||||
@ -251,7 +273,10 @@ gfxSVGGlyphsDocument::GetGlyphElement(uint32_t aGlyphId)
|
||||
return mGlyphIdMap.Get(aGlyphId);
|
||||
}
|
||||
|
||||
gfxSVGGlyphsDocument::gfxSVGGlyphsDocument(const uint8_t *aBuffer, uint32_t aBufLen)
|
||||
gfxSVGGlyphsDocument::gfxSVGGlyphsDocument(const uint8_t *aBuffer,
|
||||
uint32_t aBufLen,
|
||||
gfxSVGGlyphs *aSVGGlyphs)
|
||||
: mOwner(aSVGGlyphs)
|
||||
{
|
||||
ParseDocument(aBuffer, aBufLen);
|
||||
if (!mDocument) {
|
||||
@ -274,6 +299,22 @@ gfxSVGGlyphsDocument::gfxSVGGlyphsDocument(const uint8_t *aBuffer, uint32_t aBuf
|
||||
FindGlyphElements(root);
|
||||
}
|
||||
|
||||
gfxSVGGlyphsDocument::~gfxSVGGlyphsDocument()
|
||||
{
|
||||
if (mDocument) {
|
||||
nsSMILAnimationController* controller = mDocument->GetAnimationController();
|
||||
if (controller) {
|
||||
controller->Pause(nsSMILTimeContainer::PAUSE_PAGEHIDE);
|
||||
}
|
||||
}
|
||||
if (mPresShell) {
|
||||
mPresShell->RemovePostRefreshObserver(this);
|
||||
}
|
||||
if (mViewer) {
|
||||
mViewer->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
static nsresult
|
||||
CreateBufferedStream(const uint8_t *aBuffer, uint32_t aBufLen,
|
||||
nsCOMPtr<nsIInputStream> &aResult)
|
||||
@ -339,6 +380,8 @@ gfxSVGGlyphsDocument::ParseDocument(const uint8_t *aBuffer, uint32_t aBufLen)
|
||||
|
||||
channel->SetOwner(principal);
|
||||
|
||||
// Set this early because various decisions during page-load depend on it.
|
||||
document->SetIsBeingUsedAsImage();
|
||||
document->SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED);
|
||||
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
|
@ -17,6 +17,9 @@
|
||||
#include "gfxPattern.h"
|
||||
#include "gfxFont.h"
|
||||
#include "mozilla/gfx/UserData.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
|
||||
class gfxSVGGlyphs;
|
||||
|
||||
|
||||
/**
|
||||
@ -27,21 +30,20 @@
|
||||
* Finds and looks up elements contained in the SVG document which have glyph
|
||||
* mappings to be drawn by gfxSVGGlyphs
|
||||
*/
|
||||
class gfxSVGGlyphsDocument
|
||||
class gfxSVGGlyphsDocument MOZ_FINAL : public nsAPostRefreshObserver
|
||||
{
|
||||
typedef mozilla::dom::Element Element;
|
||||
typedef gfxFont::DrawMode DrawMode;
|
||||
|
||||
public:
|
||||
gfxSVGGlyphsDocument(const uint8_t *aBuffer, uint32_t aBufLen);
|
||||
gfxSVGGlyphsDocument(const uint8_t *aBuffer, uint32_t aBufLen,
|
||||
gfxSVGGlyphs *aSVGGlyphs);
|
||||
|
||||
Element *GetGlyphElement(uint32_t aGlyphId);
|
||||
|
||||
~gfxSVGGlyphsDocument() {
|
||||
if (mViewer) {
|
||||
mViewer->Destroy();
|
||||
}
|
||||
}
|
||||
~gfxSVGGlyphsDocument();
|
||||
|
||||
virtual void DidRefresh() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsresult ParseDocument(const uint8_t *aBuffer, uint32_t aBufLen);
|
||||
@ -52,6 +54,8 @@ private:
|
||||
|
||||
void InsertGlyphId(Element *aGlyphElement);
|
||||
|
||||
// Weak so as not to create a cycle. mOwner owns us so this can't dangle.
|
||||
gfxSVGGlyphs* mOwner;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsIContentViewer> mViewer;
|
||||
nsCOMPtr<nsIPresShell> mPresShell;
|
||||
@ -83,13 +87,18 @@ public:
|
||||
* that are passed in, and will hb_blob_destroy() them when finished;
|
||||
* the caller should -not- destroy these references.
|
||||
*/
|
||||
gfxSVGGlyphs(hb_blob_t *aSVGTable);
|
||||
gfxSVGGlyphs(hb_blob_t *aSVGTable, gfxFontEntry *aFontEntry);
|
||||
|
||||
/**
|
||||
* Releases our references to the SVG table.
|
||||
* Releases our references to the SVG table and cleans up everything else.
|
||||
*/
|
||||
~gfxSVGGlyphs();
|
||||
|
||||
/**
|
||||
* This is called when the refresh driver has ticked.
|
||||
*/
|
||||
void DidRefresh();
|
||||
|
||||
/**
|
||||
* Find the |gfxSVGGlyphsDocument| containing an SVG glyph for |aGlyphId|.
|
||||
* If |aGlyphId| does not map to an SVG document, return null.
|
||||
@ -126,6 +135,7 @@ private:
|
||||
nsBaseHashtable<nsUint32HashKey, Element*, Element*> mGlyphIdMap;
|
||||
|
||||
hb_blob_t *mSVGData;
|
||||
gfxFontEntry *mFontEntry;
|
||||
|
||||
const struct Header {
|
||||
mozilla::AutoSwap_PRUint16 mVersion;
|
||||
|
Loading…
Reference in New Issue
Block a user