Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef mozilla_gfx_DrawTargetCG_h |
michael@0 | 7 | #define mozilla_gfx_DrawTargetCG_h |
michael@0 | 8 | |
michael@0 | 9 | #include <ApplicationServices/ApplicationServices.h> |
michael@0 | 10 | |
michael@0 | 11 | #include "2D.h" |
michael@0 | 12 | #include "Rect.h" |
michael@0 | 13 | #include "PathCG.h" |
michael@0 | 14 | #include "SourceSurfaceCG.h" |
michael@0 | 15 | #include "GLDefs.h" |
michael@0 | 16 | #include "Tools.h" |
michael@0 | 17 | |
michael@0 | 18 | namespace mozilla { |
michael@0 | 19 | namespace gfx { |
michael@0 | 20 | |
michael@0 | 21 | static inline CGAffineTransform |
michael@0 | 22 | GfxMatrixToCGAffineTransform(Matrix m) |
michael@0 | 23 | { |
michael@0 | 24 | CGAffineTransform t; |
michael@0 | 25 | t.a = m._11; |
michael@0 | 26 | t.b = m._12; |
michael@0 | 27 | t.c = m._21; |
michael@0 | 28 | t.d = m._22; |
michael@0 | 29 | t.tx = m._31; |
michael@0 | 30 | t.ty = m._32; |
michael@0 | 31 | return t; |
michael@0 | 32 | } |
michael@0 | 33 | |
michael@0 | 34 | static inline Rect |
michael@0 | 35 | CGRectToRect(CGRect rect) |
michael@0 | 36 | { |
michael@0 | 37 | return Rect(rect.origin.x, |
michael@0 | 38 | rect.origin.y, |
michael@0 | 39 | rect.size.width, |
michael@0 | 40 | rect.size.height); |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | static inline Point |
michael@0 | 44 | CGPointToPoint(CGPoint point) |
michael@0 | 45 | { |
michael@0 | 46 | return Point(point.x, point.y); |
michael@0 | 47 | } |
michael@0 | 48 | |
michael@0 | 49 | static inline void |
michael@0 | 50 | SetStrokeOptions(CGContextRef cg, const StrokeOptions &aStrokeOptions) |
michael@0 | 51 | { |
michael@0 | 52 | switch (aStrokeOptions.mLineCap) |
michael@0 | 53 | { |
michael@0 | 54 | case CapStyle::BUTT: |
michael@0 | 55 | CGContextSetLineCap(cg, kCGLineCapButt); |
michael@0 | 56 | break; |
michael@0 | 57 | case CapStyle::ROUND: |
michael@0 | 58 | CGContextSetLineCap(cg, kCGLineCapRound); |
michael@0 | 59 | break; |
michael@0 | 60 | case CapStyle::SQUARE: |
michael@0 | 61 | CGContextSetLineCap(cg, kCGLineCapSquare); |
michael@0 | 62 | break; |
michael@0 | 63 | } |
michael@0 | 64 | |
michael@0 | 65 | switch (aStrokeOptions.mLineJoin) |
michael@0 | 66 | { |
michael@0 | 67 | case JoinStyle::BEVEL: |
michael@0 | 68 | CGContextSetLineJoin(cg, kCGLineJoinBevel); |
michael@0 | 69 | break; |
michael@0 | 70 | case JoinStyle::ROUND: |
michael@0 | 71 | CGContextSetLineJoin(cg, kCGLineJoinRound); |
michael@0 | 72 | break; |
michael@0 | 73 | case JoinStyle::MITER: |
michael@0 | 74 | case JoinStyle::MITER_OR_BEVEL: |
michael@0 | 75 | CGContextSetLineJoin(cg, kCGLineJoinMiter); |
michael@0 | 76 | break; |
michael@0 | 77 | } |
michael@0 | 78 | |
michael@0 | 79 | CGContextSetLineWidth(cg, aStrokeOptions.mLineWidth); |
michael@0 | 80 | CGContextSetMiterLimit(cg, aStrokeOptions.mMiterLimit); |
michael@0 | 81 | |
michael@0 | 82 | // XXX: rename mDashLength to dashLength |
michael@0 | 83 | if (aStrokeOptions.mDashLength > 0) { |
michael@0 | 84 | // we use a regular array instead of a std::vector here because we don't want to leak the <vector> include |
michael@0 | 85 | CGFloat *dashes = new CGFloat[aStrokeOptions.mDashLength]; |
michael@0 | 86 | for (size_t i=0; i<aStrokeOptions.mDashLength; i++) { |
michael@0 | 87 | dashes[i] = aStrokeOptions.mDashPattern[i]; |
michael@0 | 88 | } |
michael@0 | 89 | CGContextSetLineDash(cg, aStrokeOptions.mDashOffset, dashes, aStrokeOptions.mDashLength); |
michael@0 | 90 | delete[] dashes; |
michael@0 | 91 | } |
michael@0 | 92 | } |
michael@0 | 93 | |
michael@0 | 94 | |
michael@0 | 95 | class DrawTargetCG : public DrawTarget |
michael@0 | 96 | { |
michael@0 | 97 | public: |
michael@0 | 98 | MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCG) |
michael@0 | 99 | friend class BorrowedCGContext; |
michael@0 | 100 | DrawTargetCG(); |
michael@0 | 101 | virtual ~DrawTargetCG(); |
michael@0 | 102 | |
michael@0 | 103 | virtual BackendType GetType() const; |
michael@0 | 104 | virtual TemporaryRef<SourceSurface> Snapshot(); |
michael@0 | 105 | |
michael@0 | 106 | virtual void DrawSurface(SourceSurface *aSurface, |
michael@0 | 107 | const Rect &aDest, |
michael@0 | 108 | const Rect &aSource, |
michael@0 | 109 | const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(), |
michael@0 | 110 | const DrawOptions &aOptions = DrawOptions()); |
michael@0 | 111 | virtual void DrawFilter(FilterNode *aNode, |
michael@0 | 112 | const Rect &aSourceRect, |
michael@0 | 113 | const Point &aDestPoint, |
michael@0 | 114 | const DrawOptions &aOptions = DrawOptions()); |
michael@0 | 115 | virtual void MaskSurface(const Pattern &aSource, |
michael@0 | 116 | SourceSurface *aMask, |
michael@0 | 117 | Point aOffset, |
michael@0 | 118 | const DrawOptions &aOptions = DrawOptions()); |
michael@0 | 119 | |
michael@0 | 120 | virtual void FillRect(const Rect &aRect, |
michael@0 | 121 | const Pattern &aPattern, |
michael@0 | 122 | const DrawOptions &aOptions = DrawOptions()); |
michael@0 | 123 | |
michael@0 | 124 | |
michael@0 | 125 | //XXX: why do we take a reference to SurfaceFormat? |
michael@0 | 126 | bool Init(BackendType aType, const IntSize &aSize, SurfaceFormat&); |
michael@0 | 127 | bool Init(BackendType aType, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat); |
michael@0 | 128 | bool Init(CGContextRef cgContext, const IntSize &aSize); |
michael@0 | 129 | |
michael@0 | 130 | // Flush if using IOSurface context |
michael@0 | 131 | virtual void Flush(); |
michael@0 | 132 | |
michael@0 | 133 | virtual void DrawSurfaceWithShadow(SourceSurface *, const Point &, const Color &, const Point &, Float, CompositionOp); |
michael@0 | 134 | virtual void ClearRect(const Rect &); |
michael@0 | 135 | virtual void CopySurface(SourceSurface *, const IntRect&, const IntPoint&); |
michael@0 | 136 | virtual void StrokeRect(const Rect &, const Pattern &, const StrokeOptions&, const DrawOptions&); |
michael@0 | 137 | virtual void StrokeLine(const Point &, const Point &, const Pattern &, const StrokeOptions &, const DrawOptions &); |
michael@0 | 138 | virtual void Stroke(const Path *, const Pattern &, const StrokeOptions &, const DrawOptions &); |
michael@0 | 139 | virtual void Fill(const Path *, const Pattern &, const DrawOptions &); |
michael@0 | 140 | virtual void FillGlyphs(ScaledFont *, const GlyphBuffer&, const Pattern &, const DrawOptions &, const GlyphRenderingOptions *); |
michael@0 | 141 | virtual void Mask(const Pattern &aSource, |
michael@0 | 142 | const Pattern &aMask, |
michael@0 | 143 | const DrawOptions &aOptions = DrawOptions()); |
michael@0 | 144 | virtual void PushClip(const Path *); |
michael@0 | 145 | virtual void PushClipRect(const Rect &aRect); |
michael@0 | 146 | virtual void PopClip(); |
michael@0 | 147 | virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromNativeSurface(const NativeSurface&) const { return nullptr;} |
michael@0 | 148 | virtual TemporaryRef<DrawTarget> CreateSimilarDrawTarget(const IntSize &, SurfaceFormat) const; |
michael@0 | 149 | virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule) const; |
michael@0 | 150 | virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *, uint32_t, |
michael@0 | 151 | ExtendMode aExtendMode = ExtendMode::CLAMP) const; |
michael@0 | 152 | virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType); |
michael@0 | 153 | |
michael@0 | 154 | virtual void *GetNativeSurface(NativeSurfaceType); |
michael@0 | 155 | |
michael@0 | 156 | virtual IntSize GetSize() { return mSize; } |
michael@0 | 157 | |
michael@0 | 158 | |
michael@0 | 159 | /* This is for creating good compatible surfaces */ |
michael@0 | 160 | virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData, |
michael@0 | 161 | const IntSize &aSize, |
michael@0 | 162 | int32_t aStride, |
michael@0 | 163 | SurfaceFormat aFormat) const; |
michael@0 | 164 | virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const; |
michael@0 | 165 | CGContextRef GetCGContext() { |
michael@0 | 166 | return mCg; |
michael@0 | 167 | } |
michael@0 | 168 | private: |
michael@0 | 169 | void MarkChanged(); |
michael@0 | 170 | |
michael@0 | 171 | IntSize mSize; |
michael@0 | 172 | CGColorSpaceRef mColorSpace; |
michael@0 | 173 | CGContextRef mCg; |
michael@0 | 174 | |
michael@0 | 175 | /** |
michael@0 | 176 | * The image buffer, if the buffer is owned by this class. |
michael@0 | 177 | * If the DrawTarget was created for a pre-existing buffer or if the buffer's |
michael@0 | 178 | * lifetime is managed by CoreGraphics, mData will be null. |
michael@0 | 179 | * Data owned by DrawTargetCG will be deallocated in the destructor. |
michael@0 | 180 | */ |
michael@0 | 181 | AlignedArray<uint8_t> mData; |
michael@0 | 182 | |
michael@0 | 183 | RefPtr<SourceSurfaceCGContext> mSnapshot; |
michael@0 | 184 | }; |
michael@0 | 185 | |
michael@0 | 186 | } |
michael@0 | 187 | } |
michael@0 | 188 | |
michael@0 | 189 | #endif |
michael@0 | 190 |