/* 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/. */
namespace dom { class
HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrOffscreenCanvasOrImageBitmapOrVideoFrame; using CanvasImageSource =
HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrOffscreenCanvasOrImageBitmapOrVideoFrame; class ImageBitmap; class ImageData; class UTF8StringOrCanvasGradientOrCanvasPattern; class OwningUTF8StringOrCanvasGradientOrCanvasPattern; class TextMetrics; class CanvasGradient; class CanvasPath; class CanvasPattern;
externconst mozilla::gfx::Float SIGMA_MAX;
template <typename T> class Optional;
struct CanvasBidiProcessor; class CanvasDrawObserver; class CanvasShutdownObserver;
class DOMMatrix; class DOMMatrixReadOnly; struct DOMMatrix2DInit;
/** ** CanvasRenderingContext2D
**/ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, public nsWrapperCache { protected: virtual ~CanvasRenderingContext2D();
void Reset() { // reset the rendering context to its default state // Userland polyfill is `c2d.width = c2d.width;`
SetDimensions(GetWidth(), GetHeight());
}
/** * An abstract base class to be implemented by callers wanting to be notified * that a refresh has occurred. Callers must ensure an observer is removed * before it is destroyed.
*/ virtualvoid DidRefresh() override;
// this rect is in mTarget's current user space void RedrawUser(const gfxRect& aR);
// nsISupports interface + CC
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
/** * Update CurrentState().filter with the filter description for * CurrentState().filterChain. * Flushes the PresShell if aFlushIsNeeded is true, so the world can change * if you call this function.
*/
MOZ_CAN_RUN_SCRIPT_BOUNDARY void UpdateFilter(bool aFlushIfNeeded);
protected: /** * Helper to parse a value for the letterSpacing or wordSpacing attribute. * If successful, returns the result in aValue, and the whitespace-normalized * value string in aNormalized; if unsuccessful these are left untouched.
*/ void ParseSpacing(const nsACString& aSpacing, float* aValue,
nsACString& aNormalized);
/** * The number of living nsCanvasRenderingContexts. When this goes down to * 0, we free the premultiply and unpremultiply tables, if they exist.
*/ static MOZ_THREAD_LOCAL(uintptr_t) sNumLivingContexts;
// Returns whether a filter was successfully parsed. bool ParseFilter(const nsACString& aString,
StyleOwnedSlice<StyleFilter>& aFilterChain,
ErrorResult& aError);
// Returns whether the font was successfully updated. bool SetFontInternal(const nsACString& aFont, mozilla::ErrorResult& aError);
// Helper for SetFontInternal in the case where we have no PresShell. bool SetFontInternalDisconnected(const nsACString& aFont,
mozilla::ErrorResult& aError);
// Update the resolved values for letterSpacing and wordSpacing, if present, // following a potential change to font-relative dimensions. void UpdateSpacing();
// Clears the target and updates mOpaque based on mOpaqueAttrValue and // mContextAttributesHasAlpha. void UpdateIsOpaque();
// Shared implementation for Stroke() and Stroke(CanvasPath) methods. void StrokeImpl(const mozilla::gfx::Path& aPath);
// Shared implementation for Fill() methods. void FillImpl(const mozilla::gfx::Path& aPath);
/** * Creates the error target, if it doesn't exist
*/ staticvoid EnsureErrorTarget();
/* This function ensures there is a writable pathbuilder available
*/ bool EnsureWritablePath();
// Ensures a path in UserSpace is available. void EnsureUserSpacePath( const CanvasWindingRule& aWinding = CanvasWindingRule::Nonzero);
/** * Needs to be called before updating the transform. This makes a call to * EnsureTarget() so you don't have to.
*/ void TransformCurrentPath(const mozilla::gfx::Matrix& aTransform);
// Report the fillRule has changed. void FillRuleChanged();
/** * Create the backing surfacing, if it doesn't exist. If there is an error * in creating the target then it will put sErrorTarget in place. If there * is in turn an error in creating the sErrorTarget then they would both * be null so IsTargetValid() would still return null. * * Returns true on success.
*/ bool EnsureTarget(ErrorResult& aError, const gfx::Rect* aCoveredRect = nullptr, bool aWillClear = false, bool aSkipTransform = false);
/** * This method is run at the end of the event-loop spin where * ScheduleStableStateCallback was called. * * We use it to unlock resources that need to be locked while drawing.
*/ void OnStableState();
/** * Disposes an old target and prepares to lazily create a new target. * * Parameters are the new dimensions to be used, or if either is negative, * existing dimensions will be left unchanged.
*/ void ClearTarget(int32_t aWidth = -1, int32_t aHeight = -1);
/* * Returns the target to the buffer provider. i.e. this will queue a frame for * rendering.
*/ void ReturnTarget(bool aForceReset = false);
/** * Check if the target is valid after calling EnsureTarget.
*/ bool IsTargetValid() const { return !!mTarget && mTarget != sErrorTarget.get() && !mIsContextLost;
}
/** * Returns the surface format this canvas should be allocated using. Takes * into account mOpaque, platform requirements, etc.
*/
mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
/** * Returns true if we know for sure that the pattern for a given style is * opaque. Usefull to know if we can discard the content below in certain * situations. Optionally checks if the pattern is a color pattern.
*/ bool PatternIsOpaque(Style aStyle, bool* aIsColor = nullptr) const;
nsCString& GetFont() { /* will initilize the value if not set, else does nothing */
GetCurrentFontStyle();
return CurrentState().font;
}
bool UseSoftwareRendering() const;
// Member vars
int32_t mWidth, mHeight;
// This is true when the canvas is valid, but of zero size, this requires // specific behavior on some operations. bool mZero;
// The two ways to set the opaqueness of the canvas. // mOpaqueAttrValue: Whether the <canvas> element has the moz-opaque attribute // set. Can change during the lifetime of the context. Non-standard, should // hopefully go away soon. // mContextAttributesHasAlpha: The standard way of setting canvas opaqueness. // Set at context initialization time and never changes. bool mOpaqueAttrValue; bool mContextAttributesHasAlpha;
// Determines the context's opaqueness. Is computed from mOpaqueAttrValue and // mContextAttributesHasAlpha in UpdateIsOpaque(). bool mOpaque;
// This is true when the next time our layer is retrieved we need to // recreate it (i.e. our backing surface changed) bool mResetLayer; // This is needed for drawing in drawAsyncXULElement bool mIPC;
bool mHasPendingStableStateCallback;
// If mCanvasElement is not provided, then a docshell is
nsCOMPtr<nsIDocShell> mDocShell;
// This is created lazily so it is necessary to call EnsureTarget before // accessing it. In the event of an error it will be equal to // sErrorTarget.
RefPtr<mozilla::gfx::DrawTarget> mTarget;
// Whether we should try to create an accelerated buffer provider. bool mAllowAcceleration = true; // Whether the application expects to use operations that perform poorly with // acceleration. bool mWillReadFrequently = false; // Whether to force software rendering bool mForceSoftwareRendering = false; // Whether or not we have already shutdown. bool mHasShutdown = false; // Whether or not remote canvas is currently unavailable. bool mIsContextLost = false; // Whether or not we can restore the context after restoration. bool mAllowContextRestore = true; // Which context properties apply to an SVG when calling drawImage.
CanvasContextProperties mContextProperties = CanvasContextProperties::None;
/** * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever * Redraw is called, reset to false when Render is called.
*/ bool mIsEntireFrameInvalid; /** * When this is set, the first call to Redraw(gfxRect) should set * mIsEntireFrameInvalid since we expect it will be followed by * many more Redraw calls.
*/ bool mPredictManyRedrawCalls;
/** * Flag to avoid unnecessary surface copies to FrameCaptureListeners in the * case when the canvas is not currently being drawn into and not rendered * but canvas capturing is still ongoing.
*/
Watchable<FrameCaptureState> mFrameCaptureState;
/** * We also have a device space pathbuilder. The reason for this is as * follows, when a path is being built, but the transform changes, we * can no longer keep a single path in userspace, considering there's * several 'user spaces' now. We therefore transform the current path * into device space, and add all operations to this path in device * space. * * When then finally executing a render, the Azure drawing API expects * the path to be in userspace. We could then set an identity transform * on the DrawTarget and do all drawing in device space. This is * undesirable because it requires transforming patterns, gradients, * clips, etc. into device space and it would not work for stroking. * What we do instead is convert the path back to user space when it is * drawn, and draw it with the current transform. This makes all drawing * occur correctly. * * There's never both a device space path builder and a user space path * builder present at the same time. There is also never a path and a * path builder present at the same time. When writing proceeds on an * existing path the Path is cleared and a new builder is created. * * mPath is always in user-space.
*/
RefPtr<mozilla::gfx::Path> mPath;
RefPtr<mozilla::gfx::PathBuilder> mPathBuilder; bool mPathPruned = false;
mozilla::gfx::Matrix mPathTransform; bool mPathTransformDirty = false;
void FlushPathTransform();
/** * Number of times we've invalidated before calling redraw
*/
uint32_t mInvalidateCount; staticconst uint32_t kCanvasMaxInvalidateCount = 100;
mozilla::intl::Bidi mBidiEngine;
/** * Returns true if a shadow should be drawn along with a * drawing operation.
*/ bool NeedToDrawShadow() { const ContextState& state = CurrentState();
// The spec says we should not draw shadows if the operator is OVER. // If it's over and the alpha value is zero, nothing needs to be drawn. return NS_GET_A(state.shadowColor) != 0 &&
(state.shadowBlur != 0.f || state.shadowOffset.x != 0.f ||
state.shadowOffset.y != 0.f);
}
/** * Returns true if the result of a drawing operation should be * drawn with a filter.
*/ bool NeedToApplyFilter() { return EnsureUpdatedFilter().mPrimitives.Length() > 0;
}
/** * Calls UpdateFilter if the canvas's WriteOnly state has changed between the * last call to UpdateFilter and now.
*/ const gfx::FilterDescription& EnsureUpdatedFilter() { bool isWriteOnly = mCanvasElement && mCanvasElement->IsWriteOnly(); if (CurrentState().filterSourceGraphicTainted != isWriteOnly) {
UpdateFilter(/* aFlushIfNeeded = */ true);
EnsureTarget();
}
MOZ_ASSERT(CurrentState().filterSourceGraphicTainted == isWriteOnly); return CurrentState().filter;
}
/** * Implementation of the fillText, strokeText, and measure functions with * the operation abstracted to a flag. * Returns a TextMetrics object _only_ if the operation is measure; * drawing operations (fill or stroke) always return nullptr.
*/
UniquePtr<TextMetrics> DrawOrMeasureText(const nsAString& aText, float aX, float aY, const Optional<double>& aMaxWidth,
TextDrawOperation aOp,
ErrorResult& aError);
// A clip or a transform, recorded and restored in order. struct ClipState { explicit ClipState(mozilla::gfx::Path* aClip) : clip(aClip) {}
nsCString filterString{"none"};
StyleOwnedSlice<StyleFilter> filterChain; // RAII object that we obtain when we start to observer SVG filter elements // for rendering changes. When released we stop observing the SVG elements.
nsCOMPtr<ISVGFilterObserverList> autoSVGFiltersObserver;
mozilla::gfx::FilterDescription filter;
nsTArray<RefPtr<mozilla::gfx::SourceSurface>> filterAdditionalImages;
// This keeps track of whether the canvas was "tainted" or not when // we last used a filter. This is a security measure, whereby the // canvas is flipped to write-only if a cross-origin image is drawn to it. // This is to stop bad actors from reading back data they shouldn't have // access to. // // This also limits what filters we can apply to the context; in particular // feDisplacementMap is restricted. // // We keep track of this to ensure that if this gets out of sync with the // tainted state of the canvas itself, we update our filters accordingly. bool filterSourceGraphicTainted = false;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.