skia2/include/core/SkStrokeRec.h
caryclark 1a7eb26664 resolution dependent path measure
When a dash is drawn through a canvas with a scaled up
matrix, path measure needs the pixel resolution through
the matrix to construct the dash with sufficient
resolution.

Pass the resolution through to path measure.

Replicate chrome bug in skia GM.

R=reed@google.com
BUG=530095
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1608353002

Review URL: https://codereview.chromium.org/1608353002
2016-01-21 07:07:02 -08:00

136 lines
3.9 KiB
C++

/*
* 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;
SK_BEGIN_REQUIRE_DENSE
class SkStrokeRec {
public:
enum InitStyle {
kHairline_InitStyle,
kFill_InitStyle
};
SkStrokeRec(InitStyle style);
SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1);
explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1);
enum Style {
kHairline_Style,
kFill_Style,
kStroke_Style,
kStrokeAndFill_Style
};
enum {
kStyleCount = kStrokeAndFill_Style + 1
};
Style getStyle() const;
SkScalar getWidth() const { return fWidth; }
SkScalar getMiter() const { return fMiterLimit; }
SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; }
SkPaint::Join getJoin() const { return (SkPaint::Join)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;
}
SkScalar getResScale() const {
return fResScale;
}
void setResScale(SkScalar rs) {
SkASSERT(rs > 0 && SkScalarIsFinite(rs));
fResScale = rs;
}
/**
* 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;
/**
* Apply these stroke parameters to a paint.
*/
void applyToPaint(SkPaint* paint) const;
/**
* Compare if two SkStrokeRecs have an equal effect on a path.
* Equal SkStrokeRecs produce equal paths. Equality of produced
* paths does not take the ResScale parameter into account.
*/
bool hasEqualEffect(const SkStrokeRec& other) const {
if (!this->needToApply()) {
return this->getStyle() == other.getStyle();
}
return fWidth == other.fWidth &&
fMiterLimit == other.fMiterLimit &&
fCap == other.fCap &&
fJoin == other.fJoin &&
fStrokeAndFill == other.fStrokeAndFill;
}
private:
void init(const SkPaint&, SkPaint::Style, SkScalar resScale);
SkScalar fResScale;
SkScalar fWidth;
SkScalar fMiterLimit;
// The following three members are packed together into a single u32.
// This is to avoid unnecessary padding and ensure binary equality for
// hashing (because the padded areas might contain garbage values).
//
// fCap and fJoin are larger than needed to avoid having to initialize
// any pad values
uint32_t fCap : 16; // SkPaint::Cap
uint32_t fJoin : 15; // SkPaint::Join
uint32_t fStrokeAndFill : 1; // bool
};
SK_END_REQUIRE_DENSE
#endif