LCOV - code coverage report
Current view: top level - dom/svg - SVGContentUtils.h (source / functions) Hit Total Coverage
Test: output.info Lines: 24 40 60.0 %
Date: 2017-07-14 16:53:18 Functions: 6 8 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef MOZILLA_SVGCONTENTUTILS_H
       8             : #define MOZILLA_SVGCONTENTUTILS_H
       9             : 
      10             : // include math.h to pick up definition of M_ maths defines e.g. M_PI
      11             : #include <math.h>
      12             : 
      13             : #include "mozilla/gfx/2D.h" // for StrokeOptions
      14             : #include "mozilla/gfx/Matrix.h"
      15             : #include "mozilla/RangedPtr.h"
      16             : #include "nsError.h"
      17             : #include "nsStringFwd.h"
      18             : #include "gfx2DGlue.h"
      19             : 
      20             : class nsIContent;
      21             : class nsIDocument;
      22             : class nsIFrame;
      23             : class nsStyleContext;
      24             : class nsStyleCoord;
      25             : class nsSVGElement;
      26             : 
      27             : namespace mozilla {
      28             : class nsSVGAnimatedTransformList;
      29             : class SVGAnimatedPreserveAspectRatio;
      30             : class SVGContextPaint;
      31             : class SVGPreserveAspectRatio;
      32             : namespace dom {
      33             : class Element;
      34             : class SVGSVGElement;
      35             : } // namespace dom
      36             : 
      37             : } // namespace mozilla
      38             : 
      39             : #define SVG_ZERO_LENGTH_PATH_FIX_FACTOR 512
      40             : 
      41             : /**
      42             :  * SVGTransformTypes controls the transforms that PrependLocalTransformsTo
      43             :  * applies.
      44             :  *
      45             :  * If aWhich is eAllTransforms, then all the transforms from the coordinate
      46             :  * space established by this element for its children to the coordinate
      47             :  * space established by this element's parent element for this element, are
      48             :  * included.
      49             :  *
      50             :  * If aWhich is eUserSpaceToParent, then only the transforms from this
      51             :  * element's userspace to the coordinate space established by its parent is
      52             :  * included. This includes any transforms introduced by the 'transform'
      53             :  * attribute, transform animations and animateMotion, but not any offsets
      54             :  * due to e.g. 'x'/'y' attributes, or any transform due to a 'viewBox'
      55             :  * attribute. (SVG userspace is defined to be the coordinate space in which
      56             :  * coordinates on an element apply.)
      57             :  *
      58             :  * If aWhich is eChildToUserSpace, then only the transforms from the
      59             :  * coordinate space established by this element for its childre to this
      60             :  * elements userspace are included. This includes any offsets due to e.g.
      61             :  * 'x'/'y' attributes, and any transform due to a 'viewBox' attribute, but
      62             :  * does not include any transforms due to the 'transform' attribute.
      63             :  */
      64             : enum SVGTransformTypes {
      65             :    eAllTransforms,
      66             :    eUserSpaceToParent,
      67             :    eChildToUserSpace
      68             : };
      69             : 
      70             : inline bool
      71             : IsSVGWhitespace(char aChar)
      72             : {
      73             :   return aChar == '\x20' || aChar == '\x9' ||
      74             :          aChar == '\xD'  || aChar == '\xA';
      75             : }
      76             : 
      77             : inline bool
      78        9356 : IsSVGWhitespace(char16_t aChar)
      79             : {
      80        7964 :   return aChar == char16_t('\x20') || aChar == char16_t('\x9') ||
      81       17320 :          aChar == char16_t('\xD')  || aChar == char16_t('\xA');
      82             : }
      83             : 
      84             : /**
      85             :  * Functions generally used by SVG Content classes. Functions here
      86             :  * should not generally depend on layout methods/classes e.g. nsSVGUtils
      87             :  */
      88             : class SVGContentUtils
      89             : {
      90             : public:
      91             :   typedef mozilla::gfx::Float Float;
      92             :   typedef mozilla::gfx::Matrix Matrix;
      93             :   typedef mozilla::gfx::Rect Rect;
      94             :   typedef mozilla::gfx::StrokeOptions StrokeOptions;
      95             :   typedef mozilla::SVGAnimatedPreserveAspectRatio SVGAnimatedPreserveAspectRatio;
      96             :   typedef mozilla::SVGPreserveAspectRatio SVGPreserveAspectRatio;
      97             : 
      98             :   /*
      99             :    * Get the outer SVG element of an nsIContent
     100             :    */
     101             :   static mozilla::dom::SVGSVGElement *GetOuterSVGElement(nsSVGElement *aSVGElement);
     102             : 
     103             :   /**
     104             :    * Activates the animation element aContent as a result of navigation to the
     105             :    * fragment identifier that identifies aContent. aContent must be an instance
     106             :    * of nsSVGAnimationElement.
     107             :    *
     108             :    * This is just a shim to allow nsSVGAnimationElement::ActivateByHyperlink to
     109             :    * be called from layout/base without adding to that directory's include paths.
     110             :    */
     111             :   static void ActivateByHyperlink(nsIContent *aContent);
     112             : 
     113             :   /**
     114             :    * Moz2D's StrokeOptions requires someone else to own its mDashPattern
     115             :    * buffer, which is a pain when you want to initialize a StrokeOptions object
     116             :    * in a helper function and pass it out. This sub-class owns the mDashPattern
     117             :    * buffer so that consumers of such a helper function don't need to worry
     118             :    * about creating it, passing it in, or deleting it. (An added benefit is
     119             :    * that in the typical case when stroke-dasharray is short it will avoid
     120             :    * allocating.)
     121             :    */
     122             :   struct AutoStrokeOptions : public StrokeOptions {
     123          84 :     AutoStrokeOptions()
     124          84 :     {
     125          84 :       MOZ_ASSERT(mDashLength == 0, "InitDashPattern() depends on this");
     126          84 :     }
     127         168 :     ~AutoStrokeOptions() {
     128          84 :       if (mDashPattern && mDashPattern != mSmallArray) {
     129           0 :         delete [] mDashPattern;
     130             :       }
     131          84 :     }
     132             :     /**
     133             :      * Creates the buffer to store the stroke-dasharray, assuming out-of-memory
     134             :      * does not occur. The buffer's address is assigned to mDashPattern and
     135             :      * returned to the caller as a non-const pointer (so that the caller can
     136             :      * initialize the values in the buffer, since mDashPattern is const).
     137             :      */
     138           0 :     Float* InitDashPattern(size_t aDashCount) {
     139           0 :       if (aDashCount <= MOZ_ARRAY_LENGTH(mSmallArray)) {
     140           0 :         mDashPattern = mSmallArray;
     141           0 :         return mSmallArray;
     142             :       }
     143           0 :       Float* nonConstArray = new (mozilla::fallible) Float[aDashCount];
     144           0 :       mDashPattern = nonConstArray;
     145           0 :       return nonConstArray;
     146             :     }
     147           0 :     void DiscardDashPattern() {
     148           0 :       if (mDashPattern && mDashPattern != mSmallArray) {
     149           0 :         delete [] mDashPattern;
     150             :       }
     151           0 :       mDashLength = 0;
     152           0 :       mDashPattern = nullptr;
     153           0 :     }
     154             :   private:
     155             :     // Most dasharrays will fit in this and save us allocating
     156             :     Float mSmallArray[16];
     157             :   };
     158             : 
     159             :   enum StrokeOptionFlags {
     160             :     eAllStrokeOptions,
     161             :     eIgnoreStrokeDashing
     162             :   };
     163             :   /**
     164             :    * Note: the linecap style returned in aStrokeOptions is not valid when
     165             :    * ShapeTypeHasNoCorners(aElement) == true && aFlags == eIgnoreStrokeDashing,
     166             :    * since when aElement has no corners the rendered linecap style depends on
     167             :    * whether or not the stroke is dashed.
     168             :    */
     169             :   static void GetStrokeOptions(AutoStrokeOptions* aStrokeOptions,
     170             :                                nsSVGElement* aElement,
     171             :                                nsStyleContext* aStyleContext,
     172             :                                mozilla::SVGContextPaint* aContextPaint,
     173             :                                StrokeOptionFlags aFlags = eAllStrokeOptions);
     174             : 
     175             :   /**
     176             :    * Returns the current computed value of the CSS property 'stroke-width' for
     177             :    * the given element. aStyleContext may be provided as an optimization.
     178             :    * aContextPaint is also optional.
     179             :    *
     180             :    * Note that this function does NOT take account of the value of the 'stroke'
     181             :    * and 'stroke-opacity' properties to, say, return zero if they are "none" or
     182             :    * "0", respectively.
     183             :    */
     184             :   static Float GetStrokeWidth(nsSVGElement* aElement,
     185             :                               nsStyleContext* aStyleContext,
     186             :                               mozilla::SVGContextPaint* aContextPaint);
     187             : 
     188             :   /*
     189             :    * Get the number of CSS px (user units) per em (i.e. the em-height in user
     190             :    * units) for an nsIContent
     191             :    *
     192             :    * XXX document the conditions under which these may fail, and what they
     193             :    * return in those cases.
     194             :    */
     195             :   static float GetFontSize(mozilla::dom::Element *aElement);
     196             :   static float GetFontSize(nsIFrame *aFrame);
     197             :   static float GetFontSize(nsStyleContext *aStyleContext);
     198             :   /*
     199             :    * Get the number of CSS px (user units) per ex (i.e. the x-height in user
     200             :    * units) for an nsIContent
     201             :    *
     202             :    * XXX document the conditions under which these may fail, and what they
     203             :    * return in those cases.
     204             :    */
     205             :   static float GetFontXHeight(mozilla::dom::Element *aElement);
     206             :   static float GetFontXHeight(nsIFrame *aFrame);
     207             :   static float GetFontXHeight(nsStyleContext *aStyleContext);
     208             : 
     209             :   /*
     210             :    * Report a localized error message to the error console.
     211             :    */
     212             :   static nsresult ReportToConsole(nsIDocument* doc,
     213             :                                   const char* aWarning,
     214             :                                   const char16_t **aParams,
     215             :                                   uint32_t aParamsLength);
     216             : 
     217             :   static Matrix GetCTM(nsSVGElement *aElement, bool aScreenCTM);
     218             : 
     219             :   /**
     220             :    * Gets the tight bounds-space stroke bounds of the non-scaling-stroked rect
     221             :    * aRect.
     222             :    * @param aToBoundsSpace transforms from source space to the space aBounds
     223             :    *        should be computed in.  Must be rectilinear.
     224             :    * @param aToNonScalingStrokeSpace transforms from source
     225             :    *        space to the space in which non-scaling stroke should be applied.
     226             :    *        Must be rectilinear.
     227             :    */
     228             :   static void
     229             :   RectilinearGetStrokeBounds(const Rect& aRect,
     230             :                              const Matrix& aToBoundsSpace,
     231             :                              const Matrix& aToNonScalingStrokeSpace,
     232             :                              float aStrokeWidth,
     233             :                              Rect* aBounds);
     234             : 
     235             :   /**
     236             :    * Check if this is one of the SVG elements that SVG 1.1 Full says
     237             :    * establishes a viewport: svg, symbol, image or foreignObject.
     238             :    */
     239             :   static bool EstablishesViewport(nsIContent *aContent);
     240             : 
     241             :   static nsSVGElement*
     242             :   GetNearestViewportElement(nsIContent *aContent);
     243             : 
     244             :   /* enum for specifying coordinate direction for ObjectSpace/UserSpace */
     245             :   enum ctxDirection { X, Y, XY };
     246             : 
     247             :   /**
     248             :    * Computes sqrt((aWidth^2 + aHeight^2)/2);
     249             :    */
     250             :   static double ComputeNormalizedHypotenuse(double aWidth, double aHeight);
     251             : 
     252             :   /* Returns the angle halfway between the two specified angles */
     253             :   static float
     254             :   AngleBisect(float a1, float a2);
     255             : 
     256             :   /* Generate a viewbox to viewport tranformation matrix */
     257             : 
     258             :   static Matrix
     259             :   GetViewBoxTransform(float aViewportWidth, float aViewportHeight,
     260             :                       float aViewboxX, float aViewboxY,
     261             :                       float aViewboxWidth, float aViewboxHeight,
     262             :                       const SVGAnimatedPreserveAspectRatio &aPreserveAspectRatio);
     263             : 
     264             :   static Matrix
     265             :   GetViewBoxTransform(float aViewportWidth, float aViewportHeight,
     266             :                       float aViewboxX, float aViewboxY,
     267             :                       float aViewboxWidth, float aViewboxHeight,
     268             :                       const SVGPreserveAspectRatio &aPreserveAspectRatio);
     269             : 
     270             :   static mozilla::RangedPtr<const char16_t>
     271             :   GetStartRangedPtr(const nsAString& aString);
     272             : 
     273             :   static mozilla::RangedPtr<const char16_t>
     274             :   GetEndRangedPtr(const nsAString& aString);
     275             : 
     276             :   /**
     277             :    * True if 'aCh' is a decimal digit.
     278             :    */
     279       21951 :   static inline bool IsDigit(char16_t aCh)
     280             :   {
     281       21951 :     return aCh >= '0' && aCh <= '9';
     282             :   }
     283             : 
     284             :  /**
     285             :   * Assuming that 'aCh' is a decimal digit, return its numeric value.
     286             :   */
     287        8797 :   static inline uint32_t DecimalDigitValue(char16_t aCh)
     288             :   {
     289        8797 :     MOZ_ASSERT(IsDigit(aCh), "Digit expected");
     290        8797 :     return aCh - '0';
     291             :   }
     292             : 
     293             :   /**
     294             :    * Parses the sign (+ or -) of a number and moves aIter to the next
     295             :    * character if a sign is found.
     296             :    * @param aSignMultiplier [outparam] -1 if the sign is negative otherwise 1
     297             :    * @return false if we hit the end of the string (i.e. if aIter is initially
     298             :    *         at aEnd, or if we reach aEnd right after the sign character).
     299             :    */
     300             :   static inline bool
     301        3483 :   ParseOptionalSign(mozilla::RangedPtr<const char16_t>& aIter,
     302             :                     const mozilla::RangedPtr<const char16_t>& aEnd,
     303             :                     int32_t& aSignMultiplier)
     304             :   {
     305        3483 :     if (aIter == aEnd) {
     306           0 :       return false;
     307             :     }
     308        3483 :     aSignMultiplier = *aIter == '-' ? -1 : 1;
     309             : 
     310        3483 :     mozilla::RangedPtr<const char16_t> iter(aIter);
     311             : 
     312        3483 :     if (*iter == '-' || *iter == '+') {
     313         737 :       ++iter;
     314         737 :       if (iter == aEnd) {
     315           0 :         return false;
     316             :       }
     317             :     }
     318        3483 :     aIter = iter;
     319        3483 :     return true;
     320             :   }
     321             : 
     322             :   /**
     323             :    * Parse a number of the form:
     324             :    * number ::= integer ([Ee] integer)? | [+-]? [0-9]* "." [0-9]+ ([Ee] integer)?
     325             :    * Parsing fails if the number cannot be represented by a floatType.
     326             :    * If parsing succeeds, aIter is updated so that it points to the character
     327             :    * after the end of the number, otherwise it is left unchanged
     328             :    */
     329             :   template<class floatType>
     330             :   static bool
     331             :   ParseNumber(mozilla::RangedPtr<const char16_t>& aIter,
     332             :               const mozilla::RangedPtr<const char16_t>& aEnd,
     333             :               floatType& aValue);
     334             : 
     335             :   /**
     336             :    * Parse a number of the form:
     337             :    * number ::= integer ([Ee] integer)? | [+-]? [0-9]* "." [0-9]+ ([Ee] integer)?
     338             :    * Parsing fails if there is anything left over after the number,
     339             :    * or the number cannot be represented by a floatType.
     340             :    */
     341             :   template<class floatType>
     342             :   static bool
     343             :   ParseNumber(const nsAString& aString, floatType& aValue);
     344             : 
     345             :   /**
     346             :    * Parse an integer of the form:
     347             :    * integer ::= [+-]? [0-9]+
     348             :    * The returned number is clamped to an int32_t if outside that range.
     349             :    * If parsing succeeds, aIter is updated so that it points to the character
     350             :    * after the end of the number, otherwise it is left unchanged
     351             :    */
     352             :   static bool ParseInteger(mozilla::RangedPtr<const char16_t>& aIter,
     353             :                            const mozilla::RangedPtr<const char16_t>& aEnd,
     354             :                            int32_t& aValue);
     355             : 
     356             :   /**
     357             :    * Parse an integer of the form:
     358             :    * integer ::= [+-]? [0-9]+
     359             :    * The returned number is clamped to an int32_t if outside that range.
     360             :    * Parsing fails if there is anything left over after the number.
     361             :    */
     362             :   static bool ParseInteger(const nsAString& aString, int32_t& aValue);
     363             : 
     364             :   /**
     365             :    * Converts an nsStyleCoord into a userspace value.  Handles units
     366             :    * Factor (straight userspace), Coord (dimensioned), and Percent (of
     367             :    * aContent's SVG viewport)
     368             :    */
     369             :   static float CoordToFloat(nsSVGElement *aContent,
     370             :                             const nsStyleCoord &aCoord);
     371             :   /**
     372             :    * Parse the SVG path string
     373             :    * Returns a path
     374             :    * string formatted as an SVG path
     375             :    */
     376             :   static already_AddRefed<mozilla::gfx::Path>
     377             :   GetPath(const nsAString& aPathString);
     378             : 
     379             :   /**
     380             :    *  Returns true if aContent is one of the elements whose stroke is guaranteed
     381             :    *  to have no corners: circle or ellipse
     382             :    */
     383             :   static bool ShapeTypeHasNoCorners(const nsIContent* aContent);
     384             : };
     385             : 
     386             : #endif

Generated by: LCOV version 1.13