diff options
35 files changed, 369 insertions, 328 deletions
diff --git a/gyp/core.gypi b/gyp/core.gypi index 7a67224014..483064596a 100644 --- a/gyp/core.gypi +++ b/gyp/core.gypi @@ -158,6 +158,7 @@ '<(skia_src_path)/core/SkString.cpp', '<(skia_src_path)/core/SkStroke.h', '<(skia_src_path)/core/SkStroke.cpp', + '<(skia_src_path)/core/SkStrokeRec.cpp', '<(skia_src_path)/core/SkStrokerPriv.cpp', '<(skia_src_path)/core/SkStrokerPriv.h', '<(skia_src_path)/core/SkTemplatesPriv.h', @@ -251,6 +252,7 @@ '<(skia_include_path)/core/SkShader.h', '<(skia_include_path)/core/SkStream.h', '<(skia_include_path)/core/SkString.h', + '<(skia_include_path)/core/SkStrokeRec.h', '<(skia_include_path)/core/SkTArray.h', '<(skia_include_path)/core/SkTDArray.h', '<(skia_include_path)/core/SkTDStack.h', diff --git a/include/core/SkPath.h b/include/core/SkPath.h index 98d775222b..9d7e6a13f6 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -89,7 +89,7 @@ public: } /** Returns true if the filltype is one of the Inverse variants */ - bool isInverseFillType() const { return IsInverseFill((FillType)fFillType); } + bool isInverseFillType() const { return IsInverseFillType((FillType)fFillType); } /** * Toggle between inverse and normal filltypes. This reverse the return @@ -524,8 +524,13 @@ public: /** * Returns whether or not a fill type is inverted + * + * kWinding_FillType -> false + * kEvenOdd_FillType -> false + * kInverseWinding_FillType -> true + * kInverseEvenOdd_FillType -> true */ - static bool IsInverseFill(FillType fill) { + static bool IsInverseFillType(FillType fill) { SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch); SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch); SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch); @@ -535,8 +540,13 @@ public: /** * Returns the equivalent non-inverted fill type to the given fill type + * + * kWinding_FillType -> kWinding_FillType + * kEvenOdd_FillType -> kEvenOdd_FillType + * kInverseWinding_FillType -> kWinding_FillType + * kInverseEvenOdd_FillType -> kEvenOdd_FillType */ - static FillType NonInverseFill(FillType fill) { + static FillType ConvertToNonInverseFillType(FillType fill) { SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch); SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch); SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch); diff --git a/include/core/SkPathEffect.h b/include/core/SkPathEffect.h index fa29a34f73..736ea9895d 100644 --- a/include/core/SkPathEffect.h +++ b/include/core/SkPathEffect.h @@ -11,91 +11,14 @@ #define SkPathEffect_DEFINED #include "SkFlattenable.h" -#include "SkPaint.h" #include "SkPath.h" #include "SkPoint.h" #include "SkRect.h" +#include "SkStrokeRec.h" #include "SkTDArray.h" class SkPath; -class SkStrokeRec { -public: - enum InitStyle { - kHairline_InitStyle, - kFill_InitStyle - }; - SkStrokeRec(InitStyle style); - - SkStrokeRec(const SkStrokeRec&); - explicit SkStrokeRec(const SkPaint&); - - enum Style { - kHairline_Style, - kFill_Style, - kStroke_Style, - kStrokeAndFill_Style - }; - - Style getStyle() const; - SkScalar getWidth() const { return fWidth; } - SkScalar getMiter() const { return fMiterLimit; } - SkPaint::Cap getCap() const { return fCap; } - SkPaint::Join getJoin() const { return fJoin; } - - bool isHairlineStyle() const { - return kHairline_Style == this->getStyle(); - } - - bool isFillStyle() const { - return kFill_Style == this->getStyle(); - } - - void setFillStyle(); - void setHairlineStyle(); - /** - * Specify the strokewidth, and optionally if you want stroke + fill. - * Note, if width==0, then this request is taken to mean: - * strokeAndFill==true -> new style will be Fill - * strokeAndFill==false -> new style will be Hairline - */ - void setStrokeStyle(SkScalar width, bool strokeAndFill = false); - - void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) { - fCap = cap; - fJoin = join; - fMiterLimit = miterLimit; - } - - /** - * Returns true if this specifes any thick stroking, i.e. applyToPath() - * will return true. - */ - bool needToApply() const { - Style style = this->getStyle(); - return (kStroke_Style == style) || (kStrokeAndFill_Style == style); - } - - /** - * Apply these stroke parameters to the src path, returning the result - * in dst. - * - * If there was no change (i.e. style == hairline or fill) this returns - * false and dst is unchanged. Otherwise returns true and the result is - * stored in dst. - * - * src and dst may be the same path. - */ - bool applyToPath(SkPath* dst, const SkPath& src) const; - -private: - SkScalar fWidth; - SkScalar fMiterLimit; - SkPaint::Cap fCap; - SkPaint::Join fJoin; - bool fStrokeAndFill; -}; - /** \class SkPathEffect SkPathEffect is the base class for objects in the SkPaint that affect diff --git a/include/core/SkStrokeRec.h b/include/core/SkStrokeRec.h new file mode 100644 index 0000000000..c5b47c25dd --- /dev/null +++ b/include/core/SkStrokeRec.h @@ -0,0 +1,92 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkStrokeRec_DEFINED +#define SkStrokeRec_DEFINED + +#include "SkPaint.h" + +class SkPath; + +class SkStrokeRec { +public: + enum InitStyle { + kHairline_InitStyle, + kFill_InitStyle + }; + SkStrokeRec(InitStyle style); + + SkStrokeRec(const SkStrokeRec&); + explicit SkStrokeRec(const SkPaint&); + + enum Style { + kHairline_Style, + kFill_Style, + kStroke_Style, + kStrokeAndFill_Style + }; + + Style getStyle() const; + SkScalar getWidth() const { return fWidth; } + SkScalar getMiter() const { return fMiterLimit; } + SkPaint::Cap getCap() const { return fCap; } + SkPaint::Join getJoin() const { return fJoin; } + + bool isHairlineStyle() const { + return kHairline_Style == this->getStyle(); + } + + bool isFillStyle() const { + return kFill_Style == this->getStyle(); + } + + void setFillStyle(); + void setHairlineStyle(); + /** + * Specify the strokewidth, and optionally if you want stroke + fill. + * Note, if width==0, then this request is taken to mean: + * strokeAndFill==true -> new style will be Fill + * strokeAndFill==false -> new style will be Hairline + */ + void setStrokeStyle(SkScalar width, bool strokeAndFill = false); + + void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) { + fCap = cap; + fJoin = join; + fMiterLimit = miterLimit; + } + + /** + * Returns true if this specifes any thick stroking, i.e. applyToPath() + * will return true. + */ + bool needToApply() const { + Style style = this->getStyle(); + return (kStroke_Style == style) || (kStrokeAndFill_Style == style); + } + + /** + * Apply these stroke parameters to the src path, returning the result + * in dst. + * + * If there was no change (i.e. style == hairline or fill) this returns + * false and dst is unchanged. Otherwise returns true and the result is + * stored in dst. + * + * src and dst may be the same path. + */ + bool applyToPath(SkPath* dst, const SkPath& src) const; + +private: + SkScalar fWidth; + SkScalar fMiterLimit; + SkPaint::Cap fCap; + SkPaint::Join fJoin; + bool fStrokeAndFill; +}; + +#endif diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 8f2ed62710..06d26829d3 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -39,7 +39,7 @@ class GrTextureParams; class GrVertexBuffer; class GrVertexBufferAllocPool; class GrSoftwarePathRenderer; -class SkStroke; +class SkStrokeRec; class GR_API GrContext : public GrRefCnt { public: @@ -411,9 +411,9 @@ public: * * @param paint describes how to color pixels. * @param path the path to draw - * @param doHairLine whether the stroke can be optimized as a hairline + * @param stroke the stroke information (width, join, cap) */ - void drawPath(const GrPaint& paint, const SkPath& path, bool doHairLine); + void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke); /** * Draws vertices with a paint. @@ -846,7 +846,7 @@ public: GrPathRenderer* getPathRenderer( const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool allowSW, GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType, @@ -910,7 +910,7 @@ private: /// draw state is left unmodified. GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw); - void internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStroke& stroke); + void internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke); GrTexture* createResizedTexture(const GrTextureDesc& desc, const GrCacheData& cacheData, diff --git a/include/gpu/GrPathRendererChain.h b/include/gpu/GrPathRendererChain.h index 1032240745..d51a4bbf15 100644 --- a/include/gpu/GrPathRendererChain.h +++ b/include/gpu/GrPathRendererChain.h @@ -17,7 +17,7 @@ class GrContext; class GrDrawTarget; class GrPathRenderer; class SkPath; -class SkStroke; +class SkStrokeRec; /** * Keeps track of an ordered list of path renderers. When a path needs to be @@ -58,7 +58,7 @@ public: whether the path can be rendered with arbitrary stencil rules or not. See comments on StencilSupport in GrPathRenderer.h. */ GrPathRenderer* getPathRenderer(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& rec, const GrDrawTarget* target, DrawType drawType, StencilSupport* stencilSupport); diff --git a/src/core/SkPathEffect.cpp b/src/core/SkPathEffect.cpp index 9e84b2f2bc..8fbe5bfa87 100644 --- a/src/core/SkPathEffect.cpp +++ b/src/core/SkPathEffect.cpp @@ -6,107 +6,9 @@ * found in the LICENSE file. */ - #include "SkPathEffect.h" #include "SkPath.h" #include "SkFlattenableBuffers.h" -#include "SkPaintDefaults.h" - -// must be < 0, since ==0 means hairline, and >0 means normal stroke -#define kStrokeRec_FillStyleWidth (-SK_Scalar1) - -SkStrokeRec::SkStrokeRec(InitStyle s) { - fWidth = (kFill_InitStyle == s) ? kStrokeRec_FillStyleWidth : 0; - fMiterLimit = SkPaintDefaults_MiterLimit; - fCap = SkPaint::kDefault_Cap; - fJoin = SkPaint::kDefault_Join; - fStrokeAndFill = false; -} - -SkStrokeRec::SkStrokeRec(const SkStrokeRec& src) { - memcpy(this, &src, sizeof(src)); -} - -SkStrokeRec::SkStrokeRec(const SkPaint& paint) { - switch (paint.getStyle()) { - case SkPaint::kFill_Style: - fWidth = kStrokeRec_FillStyleWidth; - fStrokeAndFill = false; - break; - case SkPaint::kStroke_Style: - fWidth = paint.getStrokeWidth(); - fStrokeAndFill = false; - break; - case SkPaint::kStrokeAndFill_Style: - if (0 == paint.getStrokeWidth()) { - // hairline+fill == fill - fWidth = kStrokeRec_FillStyleWidth; - fStrokeAndFill = false; - } else { - fWidth = paint.getStrokeWidth(); - fStrokeAndFill = true; - } - break; - default: - SkASSERT(!"unknown paint style"); - // fall back on just fill - fWidth = kStrokeRec_FillStyleWidth; - fStrokeAndFill = false; - break; - } - - // copy these from the paint, regardless of our "style" - fMiterLimit = paint.getStrokeMiter(); - fCap = paint.getStrokeCap(); - fJoin = paint.getStrokeJoin(); -} - -SkStrokeRec::Style SkStrokeRec::getStyle() const { - if (fWidth < 0) { - return kFill_Style; - } else if (0 == fWidth) { - return kHairline_Style; - } else { - return fStrokeAndFill ? kStrokeAndFill_Style : kStroke_Style; - } -} - -void SkStrokeRec::setFillStyle() { - fWidth = kStrokeRec_FillStyleWidth; - fStrokeAndFill = false; -} - -void SkStrokeRec::setHairlineStyle() { - fWidth = 0; - fStrokeAndFill = false; -} - -void SkStrokeRec::setStrokeStyle(SkScalar width, bool strokeAndFill) { - if (strokeAndFill && (0 == width)) { - // hairline+fill == fill - this->setFillStyle(); - } else { - fWidth = width; - fStrokeAndFill = strokeAndFill; - } -} - -#include "SkStroke.h" - -bool SkStrokeRec::applyToPath(SkPath* dst, const SkPath& src) const { - if (fWidth <= 0) { // hairline or fill - return false; - } - - SkStroke stroker; - stroker.setCap(fCap); - stroker.setJoin(fJoin); - stroker.setMiterLimit(fMiterLimit); - stroker.setWidth(fWidth); - stroker.setDoFill(fStrokeAndFill); - stroker.strokePath(src, dst); - return true; -} /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 31ee3ece3a..e7f5ce8f85 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -643,7 +643,7 @@ void SkPicturePlayback::draw(SkCanvas& canvas) { // kDrawComplete will be the signal that we have reached the end of // the command stream - static const int kDrawComplete = SK_MaxU32; + static const uint32_t kDrawComplete = SK_MaxU32; SkReader32 reader(fOpData->bytes(), fOpData->size()); TextContainer text; diff --git a/src/core/SkStroke.h b/src/core/SkStroke.h index 33a7ecba5c..48805165cb 100644 --- a/src/core/SkStroke.h +++ b/src/core/SkStroke.h @@ -32,7 +32,6 @@ public: void setMiterLimit(SkScalar); void setWidth(SkScalar); - SkScalar getWidthIfStroked() const { return fDoFill ? -SK_Scalar1 : fWidth; } bool getDoFill() const { return SkToBool(fDoFill); } void setDoFill(bool doFill) { fDoFill = SkToU8(doFill); } diff --git a/src/core/SkStrokeRec.cpp b/src/core/SkStrokeRec.cpp new file mode 100644 index 0000000000..756872bdfb --- /dev/null +++ b/src/core/SkStrokeRec.cpp @@ -0,0 +1,106 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkStrokeRec.h" +#include "SkPaintDefaults.h" + +// must be < 0, since ==0 means hairline, and >0 means normal stroke +#define kStrokeRec_FillStyleWidth (-SK_Scalar1) + +SkStrokeRec::SkStrokeRec(InitStyle s) { + fWidth = (kFill_InitStyle == s) ? kStrokeRec_FillStyleWidth : 0; + fMiterLimit = SkPaintDefaults_MiterLimit; + fCap = SkPaint::kDefault_Cap; + fJoin = SkPaint::kDefault_Join; + fStrokeAndFill = false; +} + +SkStrokeRec::SkStrokeRec(const SkStrokeRec& src) { + memcpy(this, &src, sizeof(src)); +} + +SkStrokeRec::SkStrokeRec(const SkPaint& paint) { + switch (paint.getStyle()) { + case SkPaint::kFill_Style: + fWidth = kStrokeRec_FillStyleWidth; + fStrokeAndFill = false; + break; + case SkPaint::kStroke_Style: + fWidth = paint.getStrokeWidth(); + fStrokeAndFill = false; + break; + case SkPaint::kStrokeAndFill_Style: + if (0 == paint.getStrokeWidth()) { + // hairline+fill == fill + fWidth = kStrokeRec_FillStyleWidth; + fStrokeAndFill = false; + } else { + fWidth = paint.getStrokeWidth(); + fStrokeAndFill = true; + } + break; + default: + SkASSERT(!"unknown paint style"); + // fall back on just fill + fWidth = kStrokeRec_FillStyleWidth; + fStrokeAndFill = false; + break; + } + + // copy these from the paint, regardless of our "style" + fMiterLimit = paint.getStrokeMiter(); + fCap = paint.getStrokeCap(); + fJoin = paint.getStrokeJoin(); +} + +SkStrokeRec::Style SkStrokeRec::getStyle() const { + if (fWidth < 0) { + return kFill_Style; + } else if (0 == fWidth) { + return kHairline_Style; + } else { + return fStrokeAndFill ? kStrokeAndFill_Style : kStroke_Style; + } +} + +void SkStrokeRec::setFillStyle() { + fWidth = kStrokeRec_FillStyleWidth; + fStrokeAndFill = false; +} + +void SkStrokeRec::setHairlineStyle() { + fWidth = 0; + fStrokeAndFill = false; +} + +void SkStrokeRec::setStrokeStyle(SkScalar width, bool strokeAndFill) { + if (strokeAndFill && (0 == width)) { + // hairline+fill == fill + this->setFillStyle(); + } else { + fWidth = width; + fStrokeAndFill = strokeAndFill; + } +} + +#include "SkStroke.h" + +bool SkStrokeRec::applyToPath(SkPath* dst, const SkPath& src) const { + if (fWidth <= 0) { // hairline or fill + return false; + } + + SkStroke stroker; + stroker.setCap(fCap); + stroker.setJoin(fJoin); + stroker.setMiterLimit(fMiterLimit); + stroker.setWidth(fWidth); + stroker.setDoFill(fStrokeAndFill); + stroker.strokePath(src, dst); + return true; +} + diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index f8ded78d46..e0a80d3399 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -12,7 +12,7 @@ #include "GrDrawState.h" #include "GrPathUtils.h" #include "SkString.h" -#include "SkStroke.h" +#include "SkStrokeRec.h" #include "SkTrace.h" GrAAConvexPathRenderer::GrAAConvexPathRenderer() { @@ -429,15 +429,15 @@ void create_vertices(const SegmentArray& segments, } bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { return (target->getCaps().shaderDerivativeSupport() && antiAlias && - stroke.getDoFill() && !path.isInverseFillType() && path.isConvex()); + stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()); } bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, - const SkStroke&, + const SkStrokeRec&, GrDrawTarget* target, bool antiAlias) { diff --git a/src/gpu/GrAAConvexPathRenderer.h b/src/gpu/GrAAConvexPathRenderer.h index a64596c8dd..62394a3a74 100644 --- a/src/gpu/GrAAConvexPathRenderer.h +++ b/src/gpu/GrAAConvexPathRenderer.h @@ -14,13 +14,13 @@ public: GrAAConvexPathRenderer(); virtual bool canDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const SK_OVERRIDE; protected: virtual bool onDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) SK_OVERRIDE; }; diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index 6424ad5115..347e4b5bee 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -547,10 +547,10 @@ bool GrAAHairLinePathRenderer::createGeom( } bool GrAAHairLinePathRenderer::canDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { - if ((0 != stroke.getWidthIfStroked()) || !antiAlias) { + if (!stroke.isHairlineStyle() || !antiAlias) { return false; } @@ -564,7 +564,7 @@ bool GrAAHairLinePathRenderer::canDrawPath(const SkPath& path, } bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path, - const SkStroke&, + const SkStrokeRec&, GrDrawTarget* target, bool antiAlias) { diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h index 653fd01873..20be696745 100644 --- a/src/gpu/GrAAHairLinePathRenderer.h +++ b/src/gpu/GrAAHairLinePathRenderer.h @@ -18,13 +18,13 @@ public: static GrPathRenderer* Create(GrContext* context); virtual bool canDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const SK_OVERRIDE; protected: virtual bool onDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) SK_OVERRIDE; diff --git a/src/gpu/GrAddPathRenderers_default.cpp b/src/gpu/GrAddPathRenderers_default.cpp index 9be67688d7..69be15a271 100644 --- a/src/gpu/GrAddPathRenderers_default.cpp +++ b/src/gpu/GrAddPathRenderers_default.cpp @@ -10,7 +10,6 @@ #include "GrStencilAndCoverPathRenderer.h" #include "GrAAHairLinePathRenderer.h" #include "GrAAConvexPathRenderer.h" -#include "GrSoftwarePathRenderer.h" void GrPathRenderer::AddPathRenderers(GrContext* ctx, GrPathRendererChain* chain) { if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(ctx)) { diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index fbb1a0e0a0..a596088ccf 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -14,7 +14,7 @@ #include "GrPathRenderer.h" #include "GrPaint.h" #include "SkRasterClip.h" -#include "SkStroke.h" +#include "SkStrokeRec.h" #include "GrAAConvexPathRenderer.h" #include "GrAAHairLinePathRenderer.h" #include "GrSWMaskHelper.h" @@ -62,7 +62,7 @@ void setup_drawstate_aaclip(GrGpu* gpu, bool path_needs_SW_renderer(GrContext* context, GrGpu* gpu, const SkPath& origPath, - const SkStroke& stroke, + const SkStrokeRec& stroke, bool doAA) { // the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer SkTCopyOnFirstWrite<SkPath> path(origPath); @@ -89,8 +89,7 @@ bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { // TODO: generalize this function so that when // a clip gets complex enough it can just be done in SW regardless // of whether it would invoke the GrSoftwarePathRenderer. - SkStroke stroke; - stroke.setDoFill(true); + SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { const Element* element = iter.get(); @@ -270,12 +269,11 @@ bool draw_path_in_software(GrContext* context, const SkPath& path, bool doAA, const GrIRect& resultBounds) { - SkStroke stroke; - stroke.setDoFill(true); + SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); SkAutoTUnref<GrTexture> texture( GrSWMaskHelper::DrawPathMaskToTexture(context, path, - stroke, + rec, resultBounds, doAA, NULL)); if (NULL == texture) { @@ -318,8 +316,7 @@ bool GrClipMaskManager::drawElement(GrTexture* target, if (path->isInverseFillType()) { path.writable()->toggleInverseFillType(); } - SkStroke stroke; - stroke.setDoFill(true); + SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); if (NULL == pr) { GrPathRendererChain::DrawType type; type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : @@ -354,8 +351,7 @@ bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, if (path->isInverseFillType()) { path.writable()->toggleInverseFillType(); } - SkStroke stroke; - stroke.setDoFill(true); + SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); GrPathRendererChain::DrawType type = element->isAA() ? GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : GrPathRendererChain::kStencilAndColor_DrawType; @@ -660,8 +656,7 @@ bool GrClipMaskManager::createStencilClipMask(InitialState initialState, // stencil with arbitrary stencil settings. GrPathRenderer::StencilSupport stencilSupport; - SkStroke stroke; - stroke.setDoFill(true); + SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); SkRegion::Op op = element->getOp(); @@ -975,8 +970,7 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t clipStackGenID, helper.clear(kAllIn_InitialState == initialState ? 0xFF : 0x00); - SkStroke stroke; - stroke.setDoFill(true); + SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); for (ElementList::Iter iter(elements.headIter()) ; NULL != iter.get(); iter.next()) { diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index f688b7ab67..d00e062fae 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -23,10 +23,10 @@ #include "GrSoftwarePathRenderer.h" #include "GrStencilBuffer.h" #include "GrTextStrike.h" +#include "SkStrokeRec.h" #include "SkTLazy.h" #include "SkTLS.h" #include "SkTrace.h" -#include "SkStroke.h" SK_DEFINE_INST_COUNT(GrContext) SK_DEFINE_INST_COUNT(GrDrawState) @@ -720,7 +720,7 @@ void GrContext::drawRect(const GrPaint& paint, return; } if (width >= 0) { - GrVec strokeSize;; + GrVec strokeSize; if (width > 0) { strokeSize.set(width, width); combinedMatrix.mapVectors(&strokeSize, 1); @@ -982,11 +982,10 @@ void GrContext::drawOval(const GrPaint& paint, SkPath path; path.addOval(rect); path.setFillType(SkPath::kWinding_FillType); - SkStroke stroke; - if (strokeWidth < 0) { - stroke.setDoFill(true); - } else { - stroke.setWidth(strokeWidth); + SkStrokeRec stroke(0 == strokeWidth ? SkStrokeRec::kHairline_InitStyle : + SkStrokeRec::kFill_InitStyle); + if (strokeWidth > 0) { + stroke.setStrokeStyle(strokeWidth, true); } this->internalDrawPath(paint, path, stroke); return; @@ -1058,7 +1057,7 @@ void GrContext::drawOval(const GrPaint& paint, target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); } -void GrContext::drawPath(const GrPaint& paint, const SkPath& path, bool doHairLine) { +void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { if (path.isEmpty()) { if (path.isInverseFillType()) { @@ -1067,24 +1066,27 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, bool doHairLi return; } + const SkPath* pathPtr = &path; + SkPath tmpPath; + SkStrokeRec strokeRec(stroke); + if (!strokeRec.isHairlineStyle()) { + if (strokeRec.applyToPath(&tmpPath, *pathPtr)) { + pathPtr = &tmpPath; + strokeRec.setFillStyle(); + } + } + SkRect ovalRect; - if (!path.isInverseFillType() && path.isOval(&ovalRect)) { - SkScalar width = doHairLine ? 0 : -SK_Scalar1; + if (!pathPtr->isInverseFillType() && pathPtr->isOval(&ovalRect)) { + SkScalar width = strokeRec.isHairlineStyle() ? 0 : -SK_Scalar1; this->drawOval(paint, ovalRect, width); return; } - SkStroke stroke; - if (doHairLine) { - stroke.setWidth(0); - } else { - stroke.setDoFill(true); - } - - this->internalDrawPath(paint, path, stroke); + this->internalDrawPath(paint, *pathPtr, strokeRec); } -void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStroke& stroke) { +void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { // Note that below we may sw-rasterize the path into a scratch texture. // Scratch textures can be recycled after they are returned to the texture @@ -1616,7 +1618,7 @@ GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, BufferedDraw buffer * can be individually allowed/disallowed via the "allowSW" boolean. */ GrPathRenderer* GrContext::getPathRenderer(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool allowSW, GrPathRendererChain::DrawType drawType, diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index b92b77d095..dbed7839f8 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -12,7 +12,7 @@ #include "GrDrawState.h" #include "GrPathUtils.h" #include "SkString.h" -#include "SkStroke.h" +#include "SkStrokeRec.h" #include "SkTrace.h" @@ -151,11 +151,11 @@ GR_STATIC_CONST_SAME_STENCIL(gDirectToStencil, #define STENCIL_OFF 0 // Always disable stencil (even when needed) -static inline bool single_pass_path(const SkPath& path, const SkStroke& stroke) { +static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& stroke) { #if STENCIL_OFF return true; #else - if ((0 != stroke.getWidthIfStroked()) && !path.isInverseFillType()) { + if (!stroke.isHairlineStyle() && !path.isInverseFillType()) { return path.isConvex(); } return false; @@ -164,7 +164,7 @@ static inline bool single_pass_path(const SkPath& path, const SkStroke& stroke) GrPathRenderer::StencilSupport GrDefaultPathRenderer::onGetStencilSupport( const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget*) const { if (single_pass_path(path, stroke)) { return GrPathRenderer::kNoRestriction_StencilSupport; @@ -188,7 +188,7 @@ static inline void append_countour_edge_indices(bool hairLine, } bool GrDefaultPathRenderer::createGeom(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, SkScalar srcSpaceTol, GrDrawTarget* target, GrPrimitiveType* primType, @@ -214,7 +214,7 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path, GrVertexLayout layout = 0; bool indexed = contourCnt > 1; - const bool isHairline = 0 == stroke.getWidthIfStroked(); + const bool isHairline = stroke.isHairlineStyle(); int maxIdxs = 0; if (isHairline) { @@ -238,7 +238,7 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path, return false; } - uint16_t* idxBase = reinterpret_cast<uint16_t*>(arg->indices());; + uint16_t* idxBase = reinterpret_cast<uint16_t*>(arg->indices()); uint16_t* idx = idxBase; uint16_t subpathIdxStart = 0; @@ -324,7 +324,7 @@ FINISHED: } bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target, bool stencilOnly) { @@ -360,7 +360,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, bool reverse = false; bool lastPassIsBounds; - if (0 == stroke.getWidthIfStroked()) { + if (stroke.isHairlineStyle()) { passCount = 1; if (stencilOnly) { passes[0] = &gDirectToStencil; @@ -495,16 +495,15 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, } bool GrDefaultPathRenderer::canDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { - // this class can draw any path with any fill but doesn't do any - // anti-aliasing. - return (stroke.getWidthIfStroked() <= 0) && !antiAlias; + // this class can draw any path with any fill but doesn't do any anti-aliasing. + return (stroke.isFillStyle() || stroke.isHairlineStyle()) && !antiAlias; } bool GrDefaultPathRenderer::onDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { return this->internalDrawPath(path, @@ -514,7 +513,7 @@ bool GrDefaultPathRenderer::onDrawPath(const SkPath& path, } void GrDefaultPathRenderer::onStencilPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target) { GrAssert(SkPath::kInverseEvenOdd_FillType != path.getFillType()); GrAssert(SkPath::kInverseWinding_FillType != path.getFillType()); diff --git a/src/gpu/GrDefaultPathRenderer.h b/src/gpu/GrDefaultPathRenderer.h index 657537a6ef..e602fae25f 100644 --- a/src/gpu/GrDefaultPathRenderer.h +++ b/src/gpu/GrDefaultPathRenderer.h @@ -20,32 +20,32 @@ public: GrDefaultPathRenderer(bool separateStencilSupport, bool stencilWrapOpsSupport); virtual bool canDrawPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, const GrDrawTarget*, bool antiAlias) const SK_OVERRIDE; private: virtual StencilSupport onGetStencilSupport(const SkPath&, - const SkStroke&, + const SkStrokeRec&, const GrDrawTarget*) const SK_OVERRIDE; virtual bool onDrawPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, GrDrawTarget*, bool antiAlias) SK_OVERRIDE; virtual void onStencilPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, GrDrawTarget*) SK_OVERRIDE; bool internalDrawPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, GrDrawTarget*, bool stencilOnly); bool createGeom(const SkPath&, - const SkStroke&, + const SkStrokeRec&, SkScalar srcSpaceTol, GrDrawTarget*, GrPrimitiveType*, diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 9ede7438ba..f80a4416f3 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -10,12 +10,11 @@ #include "GrDrawTarget.h" #include "GrGpuVertex.h" -#include "GrIndexBuffer.h" #include "GrRenderTarget.h" #include "GrTexture.h" #include "GrVertexBuffer.h" -#include "SkStroke.h" +#include "SkStrokeRec.h" SK_DEFINE_INST_COUNT(GrDrawTarget) @@ -785,12 +784,12 @@ void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, } } -void GrDrawTarget::stencilPath(const GrPath* path, const SkStroke& stroke, SkPath::FillType fill) { +void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path stenciling. GrAssert(NULL != path); GrAssert(fCaps.pathStencilingSupport()); - GrAssert(0 != stroke.getWidthIfStroked()); - GrAssert(!SkPath::IsInverseFill(fill)); + GrAssert(!stroke.isHairlineStyle()); + GrAssert(!SkPath::IsInverseFillType(fill)); this->onStencilPath(path, stroke, fill); } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 7aba256bad..a54dd0f152 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -28,7 +28,7 @@ class GrClipData; class GrPath; class GrVertexBuffer; -class SkStroke; +class SkStrokeRec; class GrDrawTarget : public GrRefCnt { protected: @@ -457,7 +457,7 @@ public: * winding (not inverse or hairline). It will respect the HW antialias flag * on the draw state (if possible in the 3D API). */ - void stencilPath(const GrPath*, const SkStroke& stroke, SkPath::FillType fill); + void stencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill); /** * Helper function for drawing rects. This does not use the current index @@ -992,7 +992,7 @@ protected: virtual void onDrawNonIndexed(GrPrimitiveType type, int startVertex, int vertexCount) = 0; - virtual void onStencilPath(const GrPath*, const SkStroke& stroke, SkPath::FillType fill) = 0; + virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill) = 0; // subclass overrides to be notified when clip is set. Must call // INHERITED::clipwillBeSet diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 18013c1019..b84b0f11c7 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -410,7 +410,7 @@ void GrGpu::onDrawNonIndexed(GrPrimitiveType type, this->onGpuDrawNonIndexed(type, sVertex, vertexCount); } -void GrGpu::onStencilPath(const GrPath* path, const SkStroke& stroke, SkPath::FillType fill) { +void GrGpu::onStencilPath(const GrPath* path, const SkStrokeRec&, SkPath::FillType fill) { this->handleDirtyContext(); // TODO: make this more effecient (don't copy and copy back) diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index d3a0012928..4bc4c25f00 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -570,7 +570,7 @@ private: virtual void onDrawNonIndexed(GrPrimitiveType type, int startVertex, int vertexCount) SK_OVERRIDE; - virtual void onStencilPath(const GrPath* path, const SkStroke& stroke, + virtual void onStencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE; // readies the pools to provide vertex/index data. diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 4147b3b246..51546e7baa 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -487,7 +487,9 @@ void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType, draw->fIndexBuffer = NULL; } -void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStroke& stroke, +GrInOrderDrawBuffer::StencilPath::StencilPath() : fStroke(SkStrokeRec::kFill_InitStyle) {} + +void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) { if (this->needsNewClip()) { this->recordClip(); diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index 20f0c84583..17271f8c84 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -17,7 +17,7 @@ #include "GrPath.h" #include "SkClipStack.h" -#include "SkStroke.h" +#include "SkStrokeRec.h" #include "SkTemplates.h" class GrGpu; @@ -158,8 +158,10 @@ private: }; struct StencilPath { + StencilPath(); + SkAutoTUnref<const GrPath> fPath; - SkStroke fStroke; + SkStrokeRec fStroke; SkPath::FillType fFill; }; @@ -181,7 +183,7 @@ private: virtual void onDrawNonIndexed(GrPrimitiveType primitiveType, int startVertex, int vertexCount) SK_OVERRIDE; - virtual void onStencilPath(const GrPath*, const SkStroke& stroke, SkPath::FillType) SK_OVERRIDE; + virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE; virtual bool onReserveVertexSpace(GrVertexLayout layout, int vertexCount, void** vertices) SK_OVERRIDE; diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index c84bfa8566..fa2112c410 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -14,7 +14,7 @@ #include "GrPathRendererChain.h" #include "GrStencil.h" -#include "SkStroke.h" +#include "SkStrokeRec.h" #include "SkTArray.h" class SkPath; @@ -82,7 +82,7 @@ public: * @param stroke the stroke information (width, join, cap). */ StencilSupport getStencilSupport(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target) const { GrAssert(!path.isInverseFillType()); return this->onGetStencilSupport(path, stroke, target); @@ -101,7 +101,7 @@ public: * @return true if the path can be drawn by this object, false otherwise. */ virtual bool canDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& rec, const GrDrawTarget* target, bool antiAlias) const = 0; /** @@ -114,7 +114,7 @@ public: * @param antiAlias true if anti-aliasing is required. */ bool drawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { GrAssert(this->canDrawPath(path, stroke, target, antiAlias)); @@ -131,7 +131,7 @@ public: * @param stroke the stroke information (width, join, cap) * @param target target that the path will be rendered to */ - void stencilPath(const SkPath& path, const SkStroke& stroke, GrDrawTarget* target) { + void stencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) { GrAssert(kNoSupport_StencilSupport != this->getStencilSupport(path, stroke, target)); this->onStencilPath(path, stroke, target); } @@ -141,7 +141,7 @@ protected: * Subclass overrides if it has any limitations of stenciling support. */ virtual StencilSupport onGetStencilSupport(const SkPath&, - const SkStroke&, + const SkStrokeRec&, const GrDrawTarget*) const { return kNoRestriction_StencilSupport; } @@ -150,7 +150,7 @@ protected: * Subclass implementation of drawPath() */ virtual bool onDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) = 0; @@ -158,7 +158,7 @@ protected: * Subclass implementation of stencilPath(). Subclass must override iff it ever returns * kStencilOnly in onGetStencilSupport(). */ - virtual void onStencilPath(const SkPath& path, const SkStroke& stroke, GrDrawTarget* target) { + virtual void onStencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) { GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit); GrDrawState* drawState = target->drawState(); GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index 6cb45fa10f..23f757624b 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -33,7 +33,7 @@ GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) { } GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, DrawType drawType, StencilSupport* stencilSupport) { diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index e776caa3db..32a945b8b1 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -9,7 +9,7 @@ #include "GrDrawState.h" #include "GrGpu.h" -#include "SkStroke.h" +#include "SkStrokeRec.h" // TODO: try to remove this #include #include "GrContext.h" @@ -55,24 +55,24 @@ void GrSWMaskHelper::draw(const GrRect& rect, SkRegion::Op op, /** * Draw a single path element of the clip stack into the accumulation bitmap */ -void GrSWMaskHelper::draw(const SkPath& path, const SkStroke& stroke, SkRegion::Op op, +void GrSWMaskHelper::draw(const SkPath& path, const SkStrokeRec& stroke, SkRegion::Op op, bool antiAlias, uint8_t alpha) { SkPaint paint; - SkScalar width = stroke.getWidthIfStroked(); - if (0 == width) { + if (stroke.isHairlineStyle()) { paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(SK_Scalar1); } else { - if (stroke.getDoFill()) { + if (stroke.isFillStyle()) { paint.setStyle(SkPaint::kFill_Style); } else { paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeJoin(stroke.getJoin()); paint.setStrokeCap(stroke.getCap()); - paint.setStrokeWidth(width); + paint.setStrokeWidth(stroke.getWidth()); } } + SkXfermode* mode = SkXfermode::Create(op_to_mode(op)); paint.setXfermode(mode); @@ -159,7 +159,7 @@ void GrSWMaskHelper::toTexture(GrTexture *texture, uint8_t alpha) { */ GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrIRect& resultBounds, bool antiAlias, SkMatrix* matrix) { diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h index 3ceaad36c0..daf3111d55 100644 --- a/src/gpu/GrSWMaskHelper.h +++ b/src/gpu/GrSWMaskHelper.h @@ -21,7 +21,7 @@ class GrAutoScratchTexture; class GrContext; class GrTexture; class SkPath; -class SkStroke; +class SkStrokeRec; class GrDrawTarget; /** @@ -55,7 +55,7 @@ public: bool antiAlias, uint8_t alpha); // Draw a single path into the accumuation bitmap using the specified op - void draw(const SkPath& path, const SkStroke& stroke, SkRegion::Op op, + void draw(const SkPath& path, const SkStrokeRec& stroke, SkRegion::Op op, bool antiAlias, uint8_t alpha); // Helper function to get a scratch texture suitable for capturing the @@ -75,7 +75,7 @@ public: // to the GPU. The result is returned in "result". static GrTexture* DrawPathMaskToTexture(GrContext* context, const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrIRect& resultBounds, bool antiAlias, SkMatrix* matrix); diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 36a4156369..36bdcff9ea 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -11,9 +11,9 @@ #include "GrSWMaskHelper.h" //////////////////////////////////////////////////////////////////////////////// -bool GrSoftwarePathRenderer::canDrawPath(const SkPath& path, - const SkStroke& stroke, - const GrDrawTarget* target, +bool GrSoftwarePathRenderer::canDrawPath(const SkPath&, + const SkStrokeRec&, + const GrDrawTarget*, bool antiAlias) const { if (!antiAlias || NULL == fContext) { // TODO: We could allow the SW path to also handle non-AA paths but @@ -30,7 +30,7 @@ bool GrSoftwarePathRenderer::canDrawPath(const SkPath& path, GrPathRenderer::StencilSupport GrSoftwarePathRenderer::onGetStencilSupport( const SkPath&, - const SkStroke&, + const SkStrokeRec&, const GrDrawTarget*) const { return GrPathRenderer::kNoSupport_StencilSupport; } @@ -114,7 +114,7 @@ void draw_around_inv_path(GrDrawTarget* target, //////////////////////////////////////////////////////////////////////////////// // return true on success; false on failure bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h index dd78d6b406..f8c5620f49 100644 --- a/src/gpu/GrSoftwarePathRenderer.h +++ b/src/gpu/GrSoftwarePathRenderer.h @@ -25,16 +25,16 @@ public: } virtual bool canDrawPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, const GrDrawTarget*, bool antiAlias) const SK_OVERRIDE; protected: virtual StencilSupport onGetStencilSupport(const SkPath&, - const SkStroke&, + const SkStrokeRec&, const GrDrawTarget*) const SK_OVERRIDE; virtual bool onDrawPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, GrDrawTarget*, bool antiAlias) SK_OVERRIDE; diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp index a9bddda2b2..44da3f9fd2 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp @@ -11,7 +11,7 @@ #include "GrContext.h" #include "GrGpu.h" #include "GrPath.h" -#include "SkStroke.h" +#include "SkStrokeRec.h" GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) { GrAssert(NULL != context); @@ -34,23 +34,23 @@ GrStencilAndCoverPathRenderer::~GrStencilAndCoverPathRenderer() { } bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { - return stroke.getDoFill() && + return stroke.isFillStyle() && !antiAlias && // doesn't do per-path AA, relies on the target having MSAA target->getDrawState().getStencil().isDisabled(); } GrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport( const SkPath&, - const SkStroke& , + const SkStrokeRec& , const GrDrawTarget*) const { return GrPathRenderer::kStencilOnly_StencilSupport; } void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target) { GrAssert(!path.isInverseFillType()); SkAutoTUnref<GrPath> p(fGpu->createPath(path)); @@ -58,18 +58,18 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, } bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, - const SkStroke& stroke, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { GrAssert(!antiAlias); - GrAssert(0 != stroke.getWidthIfStroked()); + GrAssert(!stroke.isHairlineStyle()); GrDrawState* drawState = target->drawState(); GrAssert(drawState->getStencil().isDisabled()); SkAutoTUnref<GrPath> p(fGpu->createPath(path)); - SkPath::FillType nonInvertedFill = SkPath::NonInverseFill(path.getFillType()); + SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(path.getFillType()); target->stencilPath(p, stroke, nonInvertedFill); // TODO: Use built in cover operation rather than a rect draw. This will require making our diff --git a/src/gpu/GrStencilAndCoverPathRenderer.h b/src/gpu/GrStencilAndCoverPathRenderer.h index 824d6490e5..9ebcec9858 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.h +++ b/src/gpu/GrStencilAndCoverPathRenderer.h @@ -26,22 +26,22 @@ public: virtual ~GrStencilAndCoverPathRenderer(); virtual bool canDrawPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, const GrDrawTarget*, bool antiAlias) const SK_OVERRIDE; protected: virtual StencilSupport onGetStencilSupport(const SkPath&, - const SkStroke&, + const SkStrokeRec&, const GrDrawTarget*) const SK_OVERRIDE; virtual bool onDrawPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, GrDrawTarget*, bool antiAlias) SK_OVERRIDE; virtual void onStencilPath(const SkPath&, - const SkStroke&, + const SkStrokeRec&, GrDrawTarget*) SK_OVERRIDE; private: diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index fdb5d37328..fd7a6891e8 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -17,6 +17,7 @@ #include "GrTextStrike.h" #include "GrTextStrike_impl.h" #include "SkPath.h" +#include "SkStrokeRec.h" enum { kGlyphMaskStage = GrPaint::kTotalStages, @@ -179,7 +180,8 @@ void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed, SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds.fTop))); GrPaint tmpPaint(fPaint); am.setPreConcat(fContext, translate, &tmpPaint); - fContext->drawPath(tmpPaint, *glyph->fPath, false); + SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); + fContext->drawPath(tmpPaint, *glyph->fPath, stroke); return; } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 296af4a168..7b06d6080b 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -19,6 +19,8 @@ #include "SkDrawProcs.h" #include "SkGlyphCache.h" #include "SkImageFilter.h" +#include "SkPathEffect.h" +#include "SkStroke.h" #include "SkUtils.h" #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 @@ -753,7 +755,7 @@ inline bool shouldDrawBlurWithCPU(const SkRect& rect, SkScalar radius) { return false; } -bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, bool doHairLine, +bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, const SkStrokeRec& stroke, SkMaskFilter* filter, const SkRegion& clip, SkBounder* bounder, GrPaint* grp) { SkMaskFilter::BlurInfo info; @@ -838,7 +840,7 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, bool doHai SkMatrix translate; translate.setTranslate(offset.fX, offset.fY); am.set(context, translate); - context->drawPath(tempPaint, devPath, doHairLine); + context->drawPath(tempPaint, devPath, stroke); // If we're doing a normal blur, we can clobber the pathTexture in the // gaussianBlur. Otherwise, we need to save it for later compositing. @@ -964,8 +966,6 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, CHECK_FOR_NODRAW_ANNOTATION(paint); CHECK_SHOULD_DRAW(draw, false); - bool doHairLine = false; - GrPaint grPaint; SkAutoCachedTexture textures[GrPaint::kMaxColorStages]; if (!skPaint2GrPaintShader(this, @@ -979,8 +979,8 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // can we cheat, and threat a thin stroke as a hairline w/ coverage // if we can, we draw lots faster (raster device does this same test) SkScalar hairlineCoverage; - if (SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage)) { - doHairLine = true; + bool doHairLine = SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage); + if (doHairLine) { grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage())); } @@ -988,7 +988,7 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // where the original path can in fact be modified in place (even though // its parameter type is const). SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); - SkPath tmpPath; + SkPath tmpPath, effectPath; if (prePathMatrix) { SkPath* result = pathPtr; @@ -1005,32 +1005,40 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // at this point we're done with prePathMatrix SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) - if (paint.getPathEffect() || - (!doHairLine && paint.getStyle() != SkPaint::kFill_Style)) { - // it is safe to use tmpPath here, even if we already used it for the - // prepathmatrix, since getFillPath can take the same object for its - // input and output safely. - doHairLine = !paint.getFillPath(*pathPtr, &tmpPath); - pathPtr = &tmpPath; + SkStrokeRec stroke(paint); + SkPathEffect* pathEffect = paint.getPathEffect(); + if (pathEffect && pathEffect->filterPath(&effectPath, *pathPtr, &stroke)) { + pathPtr = &effectPath; + } + + if (!pathEffect && doHairLine) { + stroke.setHairlineStyle(); } if (paint.getMaskFilter()) { + if (!stroke.isHairlineStyle()) { + if (stroke.applyToPath(&tmpPath, *pathPtr)) { + pathPtr = &tmpPath; + stroke.setFillStyle(); + } + } + // avoid possibly allocating a new path in transform if we can SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; // transform the path into device space pathPtr->transform(fContext->getMatrix(), devPathPtr); - if (!drawWithGPUMaskFilter(fContext, *devPathPtr, doHairLine, paint.getMaskFilter(), + if (!drawWithGPUMaskFilter(fContext, *devPathPtr, stroke, paint.getMaskFilter(), *draw.fClip, draw.fBounder, &grPaint)) { - SkPaint::Style style = doHairLine ? SkPaint::kStroke_Style : - SkPaint::kFill_Style; + SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style : + SkPaint::kFill_Style; drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(), *draw.fClip, draw.fBounder, &grPaint, style); } return; } - fContext->drawPath(grPaint, *pathPtr, doHairLine); + fContext->drawPath(grPaint, *pathPtr, stroke); } namespace { |