image/SVGDocumentWrapper.h
author Henri Sivonen <hsivonen@hsivonen.fi>
Fri, 06 Jul 2018 10:44:43 +0300
changeset 489140 4ef0f163fdeb9afeddd87b37bfd987298c038542
parent 471906 e0fe3a00acc70b4f413cd8906576ec02f87cc6c7
child 506368 a1e826769668287bd7250e85fa529a6c66bfb495
permissions -rw-r--r--
Bug 1402247 - Use encoding_rs for XPCOM string encoding conversions. r=Nika,erahm,froydnj. Correctness improvements: * UTF errors are handled safely per spec instead of dangerously truncating strings. * There are fewer converter implementations. Performance improvements: * The old code did exact buffer length math, which meant doing UTF math twice on each input string (once for length calculation and another time for conversion). Exact length math is more complicated when handling errors properly, which the old code didn't do. The new code does UTF math on the string content only once (when converting) but risks allocating more than once. There are heuristics in place to lower the probability of reallocation in cases where the double math avoidance isn't enough of a saving to absorb an allocation and memcpy. * Previously, in UTF-16 <-> UTF-8 conversions, an ASCII prefix was optimized but a single non-ASCII code point pessimized the rest of the string. The new code tries to get back on the fast ASCII path. * UTF-16 to Latin1 conversion guarantees less about handling of out-of-range input to eliminate an operation from the inner loop on x86/x86_64. * When assigning to a pre-existing string, the new code tries to reuse the old buffer instead of first releasing the old buffer and then allocating a new one. * When reallocating from the new code, the memcpy covers only the data that is part of the logical length of the old string instead of memcpying the whole capacity. (For old callers old excess memcpy behavior is preserved due to bogus callers. See bug 1472113.) * UTF-8 strings in XPConnect that are in the Latin1 range are passed to SpiderMonkey as Latin1. New features: * Conversion between UTF-8 and Latin1 is added in order to enable faster future interop between Rust code (or otherwise UTF-8-using code) and text node and SpiderMonkey code that uses Latin1. MozReview-Commit-ID: JaJuExfILM9

/* -*- 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/. */

/* This class wraps an SVG document, for use by VectorImage objects. */

#ifndef mozilla_image_SVGDocumentWrapper_h
#define mozilla_image_SVGDocumentWrapper_h

#include "mozilla/Attributes.h"

#include "nsCOMPtr.h"
#include "nsIStreamListener.h"
#include "nsIObserver.h"
#include "nsIContentViewer.h"
#include "nsWeakReference.h"
#include "nsSize.h"

class nsIPresShell;
class nsIRequest;
class nsILoadGroup;
class nsIFrame;

#define OBSERVER_SVC_CID "@mozilla.org/observer-service;1"

// undef the GetCurrentTime macro defined in WinBase.h from the MS Platform SDK
#undef GetCurrentTime

namespace mozilla {
namespace dom {
class SVGSVGElement;
class SVGDocument;
} // namespace dom

namespace image {

class SVGDocumentWrapper final : public nsIStreamListener,
                                 public nsIObserver,
                                 nsSupportsWeakReference
{
public:
  SVGDocumentWrapper();

  NS_DECL_ISUPPORTS
  NS_DECL_NSISTREAMLISTENER
  NS_DECL_NSIREQUESTOBSERVER
  NS_DECL_NSIOBSERVER

  enum Dimension {
    eWidth,
    eHeight
  };

  /**
   * Returns the wrapped document, or nullptr on failure. (No AddRef.)
   */
  mozilla::dom::SVGDocument* GetDocument();

  /**
   * Returns the root <svg> element for the wrapped document, or nullptr on
   * failure.
   */
  mozilla::dom::SVGSVGElement* GetRootSVGElem();

  /**
   * Returns the root nsIFrame* for the wrapped document, or nullptr on failure.
   *
   * @return the root nsIFrame* for the wrapped document, or nullptr on failure.
   */
  nsIFrame* GetRootLayoutFrame();

  /**
   * Returns (by reference) the nsIPresShell for the wrapped document.
   *
   * @param[out] aPresShell On success, this will be populated with a pointer
   *                        to the wrapped document's nsIPresShell.
   *
   * @return NS_OK on success, or an error code on failure.
   */
  inline nsresult  GetPresShell(nsIPresShell** aPresShell)
    { return mViewer->GetPresShell(aPresShell); }

  /**
   * Modifier to update the viewport dimensions of the wrapped document. This
   * method performs a synchronous "FlushType::Layout" on the wrapped document,
   * since a viewport-change affects layout.
   *
   * @param aViewportSize The new viewport dimensions.
   */
  void UpdateViewportBounds(const nsIntSize& aViewportSize);

  /**
   * If an SVG image's helper document has a pending notification for an
   * override on the root node's "preserveAspectRatio" attribute, then this
   * method will flush that notification so that the image can paint correctly.
   * (First, though, it sets the mIgnoreInvalidation flag so that we won't
   * notify the image's observers and trigger unwanted repaint-requests.)
   */
  void FlushImageTransformInvalidation();

  /**
   * Returns a bool indicating whether the document has any SMIL animations.
   *
   * @return true if the document has any SMIL animations. Else, false.
   */
  bool      IsAnimated();

  /**
   * Indicates whether we should currently ignore rendering invalidations sent
   * from the wrapped SVG doc.
   *
   * @return true if we should ignore invalidations sent from this SVG doc.
   */
  bool ShouldIgnoreInvalidation() { return mIgnoreInvalidation; }

  /**
   * Methods to control animation.
   */
  void StartAnimation();
  void StopAnimation();
  void ResetAnimation();
  float GetCurrentTime();
  void SetCurrentTime(float aTime);
  void TickRefreshDriver();

  /**
   * Force a layout flush of the underlying SVG document.
   */
  void FlushLayout();

private:
  ~SVGDocumentWrapper();

  nsresult SetupViewer(nsIRequest* aRequest,
                       nsIContentViewer** aViewer,
                       nsILoadGroup** aLoadGroup);
  void     DestroyViewer();
  void     RegisterForXPCOMShutdown();
  void     UnregisterForXPCOMShutdown();

  nsCOMPtr<nsIContentViewer>  mViewer;
  nsCOMPtr<nsILoadGroup>      mLoadGroup;
  nsCOMPtr<nsIStreamListener> mListener;
  bool                        mIgnoreInvalidation;
  bool                        mRegisteredForXPCOMShutdown;
};

} // namespace image
} // namespace mozilla

#endif // mozilla_image_SVGDocumentWrapper_h