123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*
- * 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 "include/core/SkStrokeRec.h"
- #include "src/core/SkPaintDefaults.h"
- // must be < 0, since ==0 means hairline, and >0 means normal stroke
- #define kStrokeRec_FillStyleWidth (-SK_Scalar1)
- SkStrokeRec::SkStrokeRec(InitStyle s) {
- fResScale = 1;
- fWidth = (kFill_InitStyle == s) ? kStrokeRec_FillStyleWidth : 0;
- fMiterLimit = SkPaintDefaults_MiterLimit;
- fCap = SkPaint::kDefault_Cap;
- fJoin = SkPaint::kDefault_Join;
- fStrokeAndFill = false;
- }
- SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkScalar resScale) {
- this->init(paint, paint.getStyle(), resScale);
- }
- SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkPaint::Style styleOverride, SkScalar resScale) {
- this->init(paint, styleOverride, resScale);
- }
- void SkStrokeRec::init(const SkPaint& paint, SkPaint::Style style, SkScalar resScale) {
- fResScale = resScale;
- switch (style) {
- 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:
- SkDEBUGFAIL("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 "src/core/SkStroke.h"
- #ifdef SK_DEBUG
- // enables tweaking these values at runtime from Viewer
- bool gDebugStrokerErrorSet = false;
- SkScalar gDebugStrokerError;
- #endif
- bool SkStrokeRec::applyToPath(SkPath* dst, const SkPath& src) const {
- if (fWidth <= 0) { // hairline or fill
- return false;
- }
- SkStroke stroker;
- stroker.setCap((SkPaint::Cap)fCap);
- stroker.setJoin((SkPaint::Join)fJoin);
- stroker.setMiterLimit(fMiterLimit);
- stroker.setWidth(fWidth);
- stroker.setDoFill(fStrokeAndFill);
- #ifdef SK_DEBUG
- stroker.setResScale(gDebugStrokerErrorSet ? gDebugStrokerError : fResScale);
- #else
- stroker.setResScale(fResScale);
- #endif
- stroker.strokePath(src, dst);
- return true;
- }
- void SkStrokeRec::applyToPaint(SkPaint* paint) const {
- if (fWidth < 0) { // fill
- paint->setStyle(SkPaint::kFill_Style);
- return;
- }
- paint->setStyle(fStrokeAndFill ? SkPaint::kStrokeAndFill_Style : SkPaint::kStroke_Style);
- paint->setStrokeWidth(fWidth);
- paint->setStrokeMiter(fMiterLimit);
- paint->setStrokeCap((SkPaint::Cap)fCap);
- paint->setStrokeJoin((SkPaint::Join)fJoin);
- }
- SkScalar SkStrokeRec::getInflationRadius() const {
- return GetInflationRadius((SkPaint::Join)fJoin, fMiterLimit, (SkPaint::Cap)fCap, fWidth);
- }
- SkScalar SkStrokeRec::GetInflationRadius(const SkPaint& paint, SkPaint::Style style) {
- SkScalar width = SkPaint::kFill_Style == style ? -SK_Scalar1 : paint.getStrokeWidth();
- return GetInflationRadius(paint.getStrokeJoin(), paint.getStrokeMiter(), paint.getStrokeCap(),
- width);
- }
- SkScalar SkStrokeRec::GetInflationRadius(SkPaint::Join join, SkScalar miterLimit, SkPaint::Cap cap,
- SkScalar strokeWidth) {
- if (strokeWidth < 0) { // fill
- return 0;
- } else if (0 == strokeWidth) {
- // FIXME: We need a "matrixScale" parameter here in order to properly handle hairlines.
- // Their with is determined in device space, unlike other strokes.
- // http://skbug.com/8157
- return SK_Scalar1;
- }
- // since we're stroked, outset the rect by the radius (and join type, caps)
- SkScalar multiplier = SK_Scalar1;
- if (SkPaint::kMiter_Join == join) {
- multiplier = SkTMax(multiplier, miterLimit);
- }
- if (SkPaint::kSquare_Cap == cap) {
- multiplier = SkTMax(multiplier, SK_ScalarSqrt2);
- }
- return strokeWidth/2 * multiplier;
- }
|