/* static */ void nsFontFaceUtils::MarkDirtyForFontChange(nsIFrame* aSubtreeRoot, const gfxUserFontEntry* aFont) { AutoTArray<nsIFrame*, 4> subtrees; subtrees.AppendElement(aSubtreeRoot); nsIPresShell* ps = aSubtreeRoot->PresContext()->PresShell(); // check descendants, iterating over subtrees that may include // additional subtrees associated with placeholders do { nsIFrame* subtreeRoot = subtrees.ElementAt(subtrees.Length() - 1); subtrees.RemoveElementAt(subtrees.Length() - 1); // Check all descendants to see if they use the font AutoTArray<nsIFrame*, 32> stack; stack.AppendElement(subtreeRoot); do { nsIFrame* f = stack.ElementAt(stack.Length() - 1); stack.RemoveElementAt(stack.Length() - 1); // if this frame uses the font, mark its descendants dirty // and skip checking its children if (FrameUsesFont(f, aFont)) { ScheduleReflow(ps, f); } else { if (f->GetType() == nsGkAtoms::placeholderFrame) { nsIFrame* oof = nsPlaceholderFrame::GetRealFrameForPlaceholder(f); if (!nsLayoutUtils::IsProperAncestorFrame(subtreeRoot, oof)) { // We have another distinct subtree we need to mark. subtrees.AppendElement(oof); } } nsIFrame::ChildListIterator lists(f); for (; !lists.IsDone(); lists.Next()) { nsFrameList::Enumerator childFrames(lists.CurrentList()); for (; !childFrames.AtEnd(); childFrames.Next()) { nsIFrame* kid = childFrames.get(); stack.AppendElement(kid); } } } } while (!stack.IsEmpty()); } while (!subtrees.IsEmpty()); }
STDMETHODIMP ia2Accessible::get_selectionRanges(IA2Range** aRanges, long *aNRanges) { if (!aRanges || !aNRanges) return E_INVALIDARG; *aNRanges = 0; AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; AutoTArray<TextRange, 1> ranges; acc->Document()->SelectionRanges(&ranges); uint32_t len = ranges.Length(); for (uint32_t idx = 0; idx < len; idx++) { if (!ranges[idx].Crop(acc)) { ranges.RemoveElementAt(idx); } } *aNRanges = ranges.Length(); *aRanges = static_cast<IA2Range*>( ::CoTaskMemAlloc(sizeof(IA2Range) * *aNRanges)); if (!*aRanges) return E_OUTOFMEMORY; for (uint32_t idx = 0; idx < static_cast<uint32_t>(*aNRanges); idx++) { AccessibleWrap* anchor = static_cast<AccessibleWrap*>(ranges[idx].StartContainer()); (*aRanges)[idx].anchor = static_cast<IAccessible2*>(anchor); anchor->AddRef(); (*aRanges)[idx].anchorOffset = ranges[idx].StartOffset(); AccessibleWrap* active = static_cast<AccessibleWrap*>(ranges[idx].EndContainer()); (*aRanges)[idx].active = static_cast<IAccessible2*>(active); active->AddRef(); (*aRanges)[idx].activeOffset = ranges[idx].EndOffset(); } return S_OK; }
// // Builds the textual representation of a selector. Called by DOM 2 CSS // StyleRule:selectorText // void nsCSSSelector::ToString(nsAString& aString, CSSStyleSheet* aSheet, bool aAppend) const { if (!aAppend) aString.Truncate(); // selectors are linked from right-to-left, so the next selector in // the linked list actually precedes this one in the resulting string AutoTArray<const nsCSSSelector*, 8> stack; for (const nsCSSSelector *s = this; s; s = s->mNext) { stack.AppendElement(s); } while (!stack.IsEmpty()) { uint32_t index = stack.Length() - 1; const nsCSSSelector *s = stack.ElementAt(index); stack.RemoveElementAt(index); s->AppendToStringWithoutCombinators(aString, aSheet, false); // Append the combinator, if needed. if (!stack.IsEmpty()) { const nsCSSSelector *next = stack.ElementAt(index - 1); char16_t oper = s->mOperator; if (next->IsPseudoElement()) { NS_ASSERTION(oper == char16_t(':'), "improperly chained pseudo element"); } else { NS_ASSERTION(oper != char16_t(0), "compound selector without combinator"); aString.Append(char16_t(' ')); if (oper != char16_t(' ')) { aString.Append(oper); aString.Append(char16_t(' ')); } } } } }
nsresult RDFContentSinkImpl::PopContext(nsIRDFResource *&aResource, RDFContentSinkState &aState, RDFContentSinkParseMode &aParseMode) { if ((nullptr == mContextStack) || (mContextStack->IsEmpty())) { return NS_ERROR_NULL_POINTER; } uint32_t i = mContextStack->Length() - 1; RDFContextStackElement &e = mContextStack->ElementAt(i); aResource = e.mResource; NS_IF_ADDREF(aResource); aState = e.mState; aParseMode = e.mParseMode; mContextStack->RemoveElementAt(i); return NS_OK; }
bool ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags) { AutoTArray<ImageContainer::OwningImage,4> images; uint32_t generationCounter; aContainer->GetCurrentImages(&images, &generationCounter); if (mLastUpdateGenerationCounter == generationCounter) { return true; } mLastUpdateGenerationCounter = generationCounter; for (int32_t i = images.Length() - 1; i >= 0; --i) { if (!images[i].mImage->IsValid()) { // Don't try to update to an invalid image. images.RemoveElementAt(i); } } if (images.IsEmpty()) { // This can happen if a ClearAllImages raced with SetCurrentImages from // another thread and ClearImagesFromImageBridge ran after the // SetCurrentImages call but before UpdateImageClientNow. // This can also happen if all images in the list are invalid. // We return true because the caller would attempt to recreate the // ImageClient otherwise, and that isn't going to help. return true; } nsTArray<Buffer> newBuffers; AutoTArray<CompositableForwarder::TimedTextureClient,4> textures; for (auto& img : images) { Image* image = img.mImage; #ifdef MOZ_WIDGET_GONK if (image->GetFormat() == ImageFormat::OVERLAY_IMAGE) { OverlayImage* overlayImage = static_cast<OverlayImage*>(image); OverlaySource source; if (overlayImage->GetSidebandStream().IsValid()) { // Duplicate GonkNativeHandle::NhObj for ipc, // since ParamTraits<GonkNativeHandle>::Write() absorbs native_handle_t. RefPtr<GonkNativeHandle::NhObj> nhObj = overlayImage->GetSidebandStream().GetDupNhObj(); GonkNativeHandle handle(nhObj); if (!handle.IsValid()) { gfxWarning() << "ImageClientSingle::UpdateImage failed in GetDupNhObj"; return false; } source.handle() = OverlayHandle(handle); } else { source.handle() = OverlayHandle(overlayImage->GetOverlayId()); } source.size() = overlayImage->GetSize(); GetForwarder()->UseOverlaySource(this, source, image->GetPictureRect()); continue; } #endif RefPtr<TextureClient> texture = image->GetTextureClient(this); const bool hasTextureClient = !!texture; for (int32_t i = mBuffers.Length() - 1; i >= 0; --i) { if (mBuffers[i].mImageSerial == image->GetSerial()) { if (hasTextureClient) { MOZ_ASSERT(image->GetTextureClient(this) == mBuffers[i].mTextureClient); } else { texture = mBuffers[i].mTextureClient; } // Remove this element from mBuffers so mBuffers only contains // images that aren't present in 'images' mBuffers.RemoveElementAt(i); } } if (!texture) { // Slow path, we should not be hitting it very often and if we do it means // we are using an Image class that is not backed by textureClient and we // should fix it. if (image->GetFormat() == ImageFormat::PLANAR_YCBCR) { PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image); const PlanarYCbCrData* data = ycbcr->GetData(); if (!data) { return false; } texture = TextureClient::CreateForYCbCr(GetForwarder(), data->mYSize, data->mCbCrSize, data->mStereoMode, TextureFlags::DEFAULT | mTextureFlags ); if (!texture) { return false; } TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY); if (!autoLock.Succeeded()) { return false; } bool status = UpdateYCbCrTextureClient(texture, *data); MOZ_ASSERT(status); if (!status) { return false; } } else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE || image->GetFormat() == ImageFormat::EGLIMAGE) { gfx::IntSize size = image->GetSize(); if (image->GetFormat() == ImageFormat::EGLIMAGE) { EGLImageImage* typedImage = image->AsEGLImageImage(); texture = EGLImageTextureData::CreateTextureClient( typedImage, size, GetForwarder(), mTextureFlags); #ifdef MOZ_WIDGET_ANDROID } else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE) { SurfaceTextureImage* typedImage = image->AsSurfaceTextureImage(); texture = AndroidSurfaceTextureData::CreateTextureClient( typedImage->GetSurfaceTexture(), size, typedImage->GetOriginPos(), GetForwarder(), mTextureFlags ); #endif } else { MOZ_ASSERT(false, "Bad ImageFormat."); } } else { RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface(); MOZ_ASSERT(surface); texture = CreateTextureClientForDrawing(surface->GetFormat(), image->GetSize(), BackendSelector::Content, mTextureFlags); if (!texture) { return false; } MOZ_ASSERT(texture->CanExposeDrawTarget()); if (!texture->Lock(OpenMode::OPEN_WRITE_ONLY)) { return false; } { // We must not keep a reference to the DrawTarget after it has been unlocked. DrawTarget* dt = texture->BorrowDrawTarget(); if (!dt) { gfxWarning() << "ImageClientSingle::UpdateImage failed in BorrowDrawTarget"; return false; } MOZ_ASSERT(surface.get()); dt->CopySurface(surface, IntRect(IntPoint(), surface->GetSize()), IntPoint()); } texture->Unlock(); } } if (!texture || !AddTextureClient(texture)) { return false; } CompositableForwarder::TimedTextureClient* t = textures.AppendElement(); t->mTextureClient = texture; t->mTimeStamp = img.mTimeStamp; t->mPictureRect = image->GetPictureRect(); t->mFrameID = img.mFrameID; t->mProducerID = img.mProducerID; Buffer* newBuf = newBuffers.AppendElement(); newBuf->mImageSerial = image->GetSerial(); newBuf->mTextureClient = texture; texture->SyncWithObject(GetForwarder()->GetSyncObject()); } GetForwarder()->UseTextures(this, textures); for (auto& b : mBuffers) { RemoveTexture(b.mTextureClient); } mBuffers.SwapElements(newBuffers); return true; }
bool ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags) { AutoTArray<ImageContainer::OwningImage,4> images; uint32_t generationCounter; aContainer->GetCurrentImages(&images, &generationCounter); if (mLastUpdateGenerationCounter == generationCounter) { return true; } mLastUpdateGenerationCounter = generationCounter; for (int32_t i = images.Length() - 1; i >= 0; --i) { if (!images[i].mImage->IsValid()) { // Don't try to update to an invalid image. images.RemoveElementAt(i); } } if (images.IsEmpty()) { // This can happen if a ClearAllImages raced with SetCurrentImages from // another thread and ClearImagesFromImageBridge ran after the // SetCurrentImages call but before UpdateImageClientNow. // This can also happen if all images in the list are invalid. // We return true because the caller would attempt to recreate the // ImageClient otherwise, and that isn't going to help. for (auto& b : mBuffers) { RemoveTexture(b.mTextureClient); } mBuffers.Clear(); return true; } nsTArray<Buffer> newBuffers; AutoTArray<CompositableForwarder::TimedTextureClient,4> textures; for (auto& img : images) { Image* image = img.mImage; RefPtr<TextureClient> texture = image->GetTextureClient(GetForwarder()); const bool hasTextureClient = !!texture; for (int32_t i = mBuffers.Length() - 1; i >= 0; --i) { if (mBuffers[i].mImageSerial == image->GetSerial()) { if (hasTextureClient) { MOZ_ASSERT(image->GetTextureClient(GetForwarder()) == mBuffers[i].mTextureClient); } else { texture = mBuffers[i].mTextureClient; } // Remove this element from mBuffers so mBuffers only contains // images that aren't present in 'images' mBuffers.RemoveElementAt(i); } } if (!texture) { // Slow path, we should not be hitting it very often and if we do it means // we are using an Image class that is not backed by textureClient and we // should fix it. texture = CreateTextureClientForImage(image, GetForwarder()); } if (!texture) { return false; } // We check if the texture's allocator is still open, since in between media // decoding a frame and adding it to the compositable, we could have // restarted the GPU process. if (!texture->GetAllocator()->IPCOpen()) { continue; } if (!AddTextureClient(texture)) { return false; } CompositableForwarder::TimedTextureClient* t = textures.AppendElement(); t->mTextureClient = texture; t->mTimeStamp = img.mTimeStamp; t->mPictureRect = image->GetPictureRect(); t->mFrameID = img.mFrameID; t->mProducerID = img.mProducerID; Buffer* newBuf = newBuffers.AppendElement(); newBuf->mImageSerial = image->GetSerial(); newBuf->mTextureClient = texture; texture->SyncWithObject(GetForwarder()->GetSyncObject()); } GetForwarder()->UseTextures(this, textures); for (auto& b : mBuffers) { RemoveTexture(b.mTextureClient); } mBuffers.SwapElements(newBuffers); return true; }
bool IsInterfaceEqualToOrInheritedFrom(REFIID aInterface, REFIID aFrom, unsigned long aVtableIndexHint) { if (aInterface == aFrom) { return true; } // We expect this array to be length 1 but that is not guaranteed by the API. AutoTArray<RefPtr<ITypeInfo>, 1> typeInfos; // Grab aInterface's ITypeInfo so that we may obtain information about its // inheritance hierarchy. RefPtr<ITypeInfo> typeInfo; if (RegisteredProxy::Find(aInterface, getter_AddRefs(typeInfo))) { typeInfos.AppendElement(Move(typeInfo)); } /** * The main loop of this function searches the hierarchy of aInterface's * parent interfaces, searching for aFrom. */ while (!typeInfos.IsEmpty()) { RefPtr<ITypeInfo> curTypeInfo(Move(typeInfos.LastElement())); typeInfos.RemoveElementAt(typeInfos.Length() - 1); TYPEATTR* typeAttr = nullptr; HRESULT hr = curTypeInfo->GetTypeAttr(&typeAttr); if (FAILED(hr)) { break; } bool isFromParentVtable = IsVtableIndexFromParentInterface(typeAttr, aVtableIndexHint); WORD numParentInterfaces = typeAttr->cImplTypes; curTypeInfo->ReleaseTypeAttr(typeAttr); typeAttr = nullptr; if (!isFromParentVtable) { // The vtable index cannot belong to this interface (otherwise the IIDs // would already have matched and we would have returned true). Since we // now also know that the vtable index cannot possibly be contained inside // curTypeInfo's parent interface, there is no point searching any further // up the hierarchy from here. OTOH we still should check any remaining // entries that are still in the typeInfos array, so we continue. continue; } for (WORD i = 0; i < numParentInterfaces; ++i) { HREFTYPE refCookie; hr = curTypeInfo->GetRefTypeOfImplType(i, &refCookie); if (FAILED(hr)) { continue; } RefPtr<ITypeInfo> nextTypeInfo; hr = curTypeInfo->GetRefTypeInfo(refCookie, getter_AddRefs(nextTypeInfo)); if (FAILED(hr)) { continue; } hr = nextTypeInfo->GetTypeAttr(&typeAttr); if (FAILED(hr)) { continue; } IID nextIid = typeAttr->guid; nextTypeInfo->ReleaseTypeAttr(typeAttr); typeAttr = nullptr; if (nextIid == aFrom) { return true; } typeInfos.AppendElement(Move(nextTypeInfo)); } } return false; }