15f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com/*
25f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * Copyright 2012 Google Inc.
35f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com *
45f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * Use of this source code is governed by a BSD-style license that can be
55f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * found in the LICENSE file.
65f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com */
75f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
85f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#ifndef SkStrokeRec_DEFINED
95f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#define SkStrokeRec_DEFINED
105f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
115f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkPaint.h"
125f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
135f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comclass SkPath;
145f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
15b68ce74bd197a9ca4becd53cbcfee825b8d08e0emtkleinSK_BEGIN_REQUIRE_DENSE
165f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comclass SkStrokeRec {
175f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.compublic:
185f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    enum InitStyle {
195f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        kHairline_InitStyle,
205f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        kFill_InitStyle
215f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    };
225f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    SkStrokeRec(InitStyle style);
2305d9044de4f1c6e791df66a425638752daac4c6breed    SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1);
2405d9044de4f1c6e791df66a425638752daac4c6breed    explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1);
255f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
265f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    enum Style {
275f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        kHairline_Style,
285f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        kFill_Style,
295f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        kStroke_Style,
305f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        kStrokeAndFill_Style
315f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    };
32b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    enum {
33b85a0aab6905af8b329539b7573a7555b727d5e5cdalton        kStyleCount = kStrokeAndFill_Style + 1
34b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    };
355f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
365f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    Style getStyle() const;
375f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    SkScalar getWidth() const { return fWidth; }
385f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    SkScalar getMiter() const { return fMiterLimit; }
39897c9937636c2287bb217c76da9a56afb43050acjvanverth    SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; }
40897c9937636c2287bb217c76da9a56afb43050acjvanverth    SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; }
415f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
425f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    bool isHairlineStyle() const {
435f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        return kHairline_Style == this->getStyle();
445f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    }
455f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
465f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    bool isFillStyle() const {
475f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        return kFill_Style == this->getStyle();
485f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    }
495f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
505f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    void setFillStyle();
515f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    void setHairlineStyle();
525f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    /**
535f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  Specify the strokewidth, and optionally if you want stroke + fill.
545f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  Note, if width==0, then this request is taken to mean:
555f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *      strokeAndFill==true -> new style will be Fill
565f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *      strokeAndFill==false -> new style will be Hairline
575f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     */
585f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    void setStrokeStyle(SkScalar width, bool strokeAndFill = false);
595f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
605f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) {
615f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        fCap = cap;
625f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        fJoin = join;
635f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        fMiterLimit = miterLimit;
645f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    }
655f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
661a7eb266644d2e1b0968dbca606ca0a91903419dcaryclark    SkScalar getResScale() const {
671a7eb266644d2e1b0968dbca606ca0a91903419dcaryclark        return fResScale;
681a7eb266644d2e1b0968dbca606ca0a91903419dcaryclark    }
691a7eb266644d2e1b0968dbca606ca0a91903419dcaryclark
70f103cd85392e30d2a534a3a62a034e79abff2d4fegdaniel    void setResScale(SkScalar rs) {
71f103cd85392e30d2a534a3a62a034e79abff2d4fegdaniel        SkASSERT(rs > 0 && SkScalarIsFinite(rs));
72f103cd85392e30d2a534a3a62a034e79abff2d4fegdaniel        fResScale = rs;
73f103cd85392e30d2a534a3a62a034e79abff2d4fegdaniel    }
74f103cd85392e30d2a534a3a62a034e79abff2d4fegdaniel
755f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    /**
765f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  Returns true if this specifes any thick stroking, i.e. applyToPath()
775f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  will return true.
785f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     */
795f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    bool needToApply() const {
805f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        Style style = this->getStyle();
815f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com        return (kStroke_Style == style) || (kStrokeAndFill_Style == style);
825f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    }
835f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
845f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    /**
855f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  Apply these stroke parameters to the src path, returning the result
865f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  in dst.
875f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *
885f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  If there was no change (i.e. style == hairline or fill) this returns
895f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  false and dst is unchanged. Otherwise returns true and the result is
905f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  stored in dst.
915f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *
925f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     *  src and dst may be the same path.
935f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com     */
945f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    bool applyToPath(SkPath* dst, const SkPath& src) const;
955f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
9620b373cf3116905fc5ca1928c9b504851335ca43cdalton    /**
9720b373cf3116905fc5ca1928c9b504851335ca43cdalton     *  Apply these stroke parameters to a paint.
9820b373cf3116905fc5ca1928c9b504851335ca43cdalton     */
9920b373cf3116905fc5ca1928c9b504851335ca43cdalton    void applyToPaint(SkPaint* paint) const;
10020b373cf3116905fc5ca1928c9b504851335ca43cdalton
1018f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen    /**
1025668648e875abe0a064caabef432ade4745deb89bsalomon     * Gives a conservative value for the outset that should applied to a
1035668648e875abe0a064caabef432ade4745deb89bsalomon     * geometries bounds to account for any inflation due to applying this
1045668648e875abe0a064caabef432ade4745deb89bsalomon     * strokeRec to the geometry.
1055668648e875abe0a064caabef432ade4745deb89bsalomon     */
1065668648e875abe0a064caabef432ade4745deb89bsalomon    SkScalar getInflationRadius() const;
1075668648e875abe0a064caabef432ade4745deb89bsalomon
1085668648e875abe0a064caabef432ade4745deb89bsalomon    /**
1095668648e875abe0a064caabef432ade4745deb89bsalomon     * Equivalent to:
1105668648e875abe0a064caabef432ade4745deb89bsalomon     *   SkStrokeRec rec(paint, style);
1115668648e875abe0a064caabef432ade4745deb89bsalomon     *   rec.getInflationRadius();
1125668648e875abe0a064caabef432ade4745deb89bsalomon     * This does not account for other effects on the paint (i.e. path
1135668648e875abe0a064caabef432ade4745deb89bsalomon     * effect).
1145668648e875abe0a064caabef432ade4745deb89bsalomon     */
1155668648e875abe0a064caabef432ade4745deb89bsalomon    static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style);
1165668648e875abe0a064caabef432ade4745deb89bsalomon
1175668648e875abe0a064caabef432ade4745deb89bsalomon    /**
1188f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen     * Compare if two SkStrokeRecs have an equal effect on a path.
1198f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen     * Equal SkStrokeRecs produce equal paths. Equality of produced
1208f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen     * paths does not take the ResScale parameter into account.
1218f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen     */
1228f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen    bool hasEqualEffect(const SkStrokeRec& other) const {
1238f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen        if (!this->needToApply()) {
1248f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen            return this->getStyle() == other.getStyle();
1258f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen        }
1268f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen        return fWidth == other.fWidth &&
1278f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen               fMiterLimit == other.fMiterLimit &&
1288f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen               fCap == other.fCap &&
1298f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen               fJoin == other.fJoin &&
1308f827fe44aad3c93638bc0f5dec32812c9ba2c98kkinnunen               fStrokeAndFill == other.fStrokeAndFill;
1315c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org    }
1325c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org
1335f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comprivate:
13405d9044de4f1c6e791df66a425638752daac4c6breed    void init(const SkPaint&, SkPaint::Style, SkScalar resScale);
135e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel
13605d9044de4f1c6e791df66a425638752daac4c6breed    SkScalar        fResScale;
1375f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    SkScalar        fWidth;
1385f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    SkScalar        fMiterLimit;
139897c9937636c2287bb217c76da9a56afb43050acjvanverth    // The following three members are packed together into a single u32.
140897c9937636c2287bb217c76da9a56afb43050acjvanverth    // This is to avoid unnecessary padding and ensure binary equality for
141897c9937636c2287bb217c76da9a56afb43050acjvanverth    // hashing (because the padded areas might contain garbage values).
142b68ce74bd197a9ca4becd53cbcfee825b8d08e0emtklein    //
143897c9937636c2287bb217c76da9a56afb43050acjvanverth    // fCap and fJoin are larger than needed to avoid having to initialize
144897c9937636c2287bb217c76da9a56afb43050acjvanverth    // any pad values
145897c9937636c2287bb217c76da9a56afb43050acjvanverth    uint32_t        fCap : 16;             // SkPaint::Cap
146897c9937636c2287bb217c76da9a56afb43050acjvanverth    uint32_t        fJoin : 15;            // SkPaint::Join
147897c9937636c2287bb217c76da9a56afb43050acjvanverth    uint32_t        fStrokeAndFill : 1;    // bool
1485f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com};
149b68ce74bd197a9ca4becd53cbcfee825b8d08e0emtkleinSK_END_REQUIRE_DENSE
1505f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
1515f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#endif
152