michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsFontFaceList.h" michael@0: #include "nsFontFace.h" michael@0: #include "nsFontFaceLoader.h" michael@0: #include "nsIFrame.h" michael@0: #include "gfxFont.h" michael@0: #include "mozilla/gfx/2D.h" michael@0: michael@0: nsFontFaceList::nsFontFaceList() michael@0: { michael@0: } michael@0: michael@0: nsFontFaceList::~nsFontFaceList() michael@0: { michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // nsISupports michael@0: michael@0: NS_IMPL_ISUPPORTS(nsFontFaceList, nsIDOMFontFaceList) michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // nsIDOMFontFaceList michael@0: michael@0: /* nsIDOMFontFace item (in unsigned long index); */ michael@0: struct FindByIndexData { michael@0: uint32_t mTarget; michael@0: uint32_t mCurrent; michael@0: nsIDOMFontFace* mResult; michael@0: }; michael@0: michael@0: static PLDHashOperator michael@0: FindByIndex(gfxFontEntry* aKey, nsIDOMFontFace* aData, void* aUserData) michael@0: { michael@0: FindByIndexData* data = static_cast(aUserData); michael@0: if (data->mCurrent == data->mTarget) { michael@0: data->mResult = aData; michael@0: return PL_DHASH_STOP; michael@0: } michael@0: data->mCurrent++; michael@0: return PL_DHASH_NEXT; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsFontFaceList::Item(uint32_t index, nsIDOMFontFace **_retval) michael@0: { michael@0: NS_ENSURE_TRUE(index < mFontFaces.Count(), NS_ERROR_INVALID_ARG); michael@0: FindByIndexData userData; michael@0: userData.mTarget = index; michael@0: userData.mCurrent = 0; michael@0: userData.mResult = nullptr; michael@0: mFontFaces.EnumerateRead(FindByIndex, &userData); michael@0: NS_ASSERTION(userData.mResult != nullptr, "null entry in nsFontFaceList?"); michael@0: NS_IF_ADDREF(*_retval = userData.mResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute unsigned long length; */ michael@0: NS_IMETHODIMP michael@0: nsFontFaceList::GetLength(uint32_t *aLength) michael@0: { michael@0: *aLength = mFontFaces.Count(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // nsFontFaceList michael@0: michael@0: nsresult michael@0: nsFontFaceList::AddFontsFromTextRun(gfxTextRun* aTextRun, michael@0: uint32_t aOffset, uint32_t aLength) michael@0: { michael@0: gfxTextRun::GlyphRunIterator iter(aTextRun, aOffset, aLength); michael@0: while (iter.NextRun()) { michael@0: gfxFontEntry *fe = iter.GetGlyphRun()->mFont->GetFontEntry(); michael@0: // if we have already listed this face, just make sure the match type is michael@0: // recorded michael@0: nsFontFace* existingFace = michael@0: static_cast(mFontFaces.GetWeak(fe)); michael@0: if (existingFace) { michael@0: existingFace->AddMatchType(iter.GetGlyphRun()->mMatchType); michael@0: } else { michael@0: // A new font entry we haven't seen before michael@0: nsRefPtr ff = michael@0: new nsFontFace(fe, aTextRun->GetFontGroup(), michael@0: iter.GetGlyphRun()->mMatchType); michael@0: mFontFaces.Put(fe, ff); michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: }