Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2012 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkStrokeRec.h"
      9 #include "SkPaintDefaults.h"
     10 
     11 // must be < 0, since ==0 means hairline, and >0 means normal stroke
     12 #define kStrokeRec_FillStyleWidth     (-SK_Scalar1)
     13 
     14 SkStrokeRec::SkStrokeRec(InitStyle s) {
     15     fResScale       = 1;
     16     fWidth          = (kFill_InitStyle == s) ? kStrokeRec_FillStyleWidth : 0;
     17     fMiterLimit     = SkPaintDefaults_MiterLimit;
     18     fCap            = SkPaint::kDefault_Cap;
     19     fJoin           = SkPaint::kDefault_Join;
     20     fStrokeAndFill  = false;
     21 }
     22 
     23 SkStrokeRec::SkStrokeRec(const SkStrokeRec& src) {
     24     memcpy(this, &src, sizeof(src));
     25 }
     26 
     27 SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkScalar resScale) {
     28     this->init(paint, paint.getStyle(), resScale);
     29 }
     30 
     31 SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkPaint::Style styleOverride, SkScalar resScale) {
     32     this->init(paint, styleOverride, resScale);
     33 }
     34 
     35 void SkStrokeRec::init(const SkPaint& paint, SkPaint::Style style, SkScalar resScale) {
     36     fResScale = resScale;
     37 
     38     switch (style) {
     39         case SkPaint::kFill_Style:
     40             fWidth = kStrokeRec_FillStyleWidth;
     41             fStrokeAndFill = false;
     42             break;
     43         case SkPaint::kStroke_Style:
     44             fWidth = paint.getStrokeWidth();
     45             fStrokeAndFill = false;
     46             break;
     47         case SkPaint::kStrokeAndFill_Style:
     48             if (0 == paint.getStrokeWidth()) {
     49                 // hairline+fill == fill
     50                 fWidth = kStrokeRec_FillStyleWidth;
     51                 fStrokeAndFill = false;
     52             } else {
     53                 fWidth = paint.getStrokeWidth();
     54                 fStrokeAndFill = true;
     55             }
     56             break;
     57         default:
     58             SkDEBUGFAIL("unknown paint style");
     59             // fall back on just fill
     60             fWidth = kStrokeRec_FillStyleWidth;
     61             fStrokeAndFill = false;
     62             break;
     63     }
     64 
     65     // copy these from the paint, regardless of our "style"
     66     fMiterLimit = paint.getStrokeMiter();
     67     fCap        = paint.getStrokeCap();
     68     fJoin       = paint.getStrokeJoin();
     69 }
     70 
     71 SkStrokeRec::Style SkStrokeRec::getStyle() const {
     72     if (fWidth < 0) {
     73         return kFill_Style;
     74     } else if (0 == fWidth) {
     75         return kHairline_Style;
     76     } else {
     77         return fStrokeAndFill ? kStrokeAndFill_Style : kStroke_Style;
     78     }
     79 }
     80 
     81 void SkStrokeRec::setFillStyle() {
     82     fWidth = kStrokeRec_FillStyleWidth;
     83     fStrokeAndFill = false;
     84 }
     85 
     86 void SkStrokeRec::setHairlineStyle() {
     87     fWidth = 0;
     88     fStrokeAndFill = false;
     89 }
     90 
     91 void SkStrokeRec::setStrokeStyle(SkScalar width, bool strokeAndFill) {
     92     if (strokeAndFill && (0 == width)) {
     93         // hairline+fill == fill
     94         this->setFillStyle();
     95     } else {
     96         fWidth = width;
     97         fStrokeAndFill = strokeAndFill;
     98     }
     99 }
    100 
    101 #include "SkStroke.h"
    102 
    103 #if !defined SK_LEGACY_STROKE_CURVES && defined SK_DEBUG
    104     // enables tweaking these values at runtime from SampleApp
    105     bool gDebugStrokerErrorSet = false;
    106     SkScalar gDebugStrokerError;
    107 #endif
    108 
    109 bool SkStrokeRec::applyToPath(SkPath* dst, const SkPath& src) const {
    110     if (fWidth <= 0) {  // hairline or fill
    111         return false;
    112     }
    113 
    114     SkStroke stroker;
    115     stroker.setCap(fCap);
    116     stroker.setJoin(fJoin);
    117     stroker.setMiterLimit(fMiterLimit);
    118     stroker.setWidth(fWidth);
    119     stroker.setDoFill(fStrokeAndFill);
    120 #if !defined SK_LEGACY_STROKE_CURVES && defined SK_DEBUG
    121     stroker.setResScale(gDebugStrokerErrorSet ? gDebugStrokerError : fResScale);
    122 #else
    123     stroker.setResScale(fResScale);
    124 #endif
    125     stroker.strokePath(src, dst);
    126     return true;
    127 }
    128 
    129 void SkStrokeRec::applyToPaint(SkPaint* paint) const {
    130     if (fWidth < 0) {  // fill
    131         paint->setStyle(SkPaint::kFill_Style);
    132         return;
    133     }
    134 
    135     paint->setStyle(fStrokeAndFill ? SkPaint::kStrokeAndFill_Style : SkPaint::kStroke_Style);
    136     paint->setStrokeWidth(fWidth);
    137     paint->setStrokeMiter(fMiterLimit);
    138     paint->setStrokeCap(fCap);
    139     paint->setStrokeJoin(fJoin);
    140 }
    141