SkLayerDrawLooper.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * Copyright 2011 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. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkColor.h"
  9. #include "include/core/SkMaskFilter.h"
  10. #include "include/core/SkString.h"
  11. #include "include/core/SkUnPreMultiply.h"
  12. #include "include/effects/SkBlurDrawLooper.h"
  13. #include "include/effects/SkLayerDrawLooper.h"
  14. #include "src/core/SkArenaAlloc.h"
  15. #include "src/core/SkBlendModePriv.h"
  16. #include "src/core/SkColorSpacePriv.h"
  17. #include "src/core/SkMaskFilterBase.h"
  18. #include "src/core/SkReadBuffer.h"
  19. #include "src/core/SkStringUtils.h"
  20. #include "src/core/SkWriteBuffer.h"
  21. #include "src/core/SkXfermodePriv.h"
  22. SkLayerDrawLooper::LayerInfo::LayerInfo() {
  23. fPaintBits = 0; // ignore our paint fields
  24. fColorMode = SkBlendMode::kDst; // ignore our color
  25. fOffset.set(0, 0);
  26. fPostTranslate = false;
  27. }
  28. SkLayerDrawLooper::SkLayerDrawLooper()
  29. : fRecs(nullptr),
  30. fCount(0) {
  31. }
  32. SkLayerDrawLooper::~SkLayerDrawLooper() {
  33. Rec* rec = fRecs;
  34. while (rec) {
  35. Rec* next = rec->fNext;
  36. delete rec;
  37. rec = next;
  38. }
  39. }
  40. SkLayerDrawLooper::Context*
  41. SkLayerDrawLooper::makeContext(SkCanvas* canvas, SkArenaAlloc* alloc) const {
  42. canvas->save();
  43. return alloc->make<LayerDrawLooperContext>(this);
  44. }
  45. static SkColor4f xferColor(const SkColor4f& src, const SkColor4f& dst, SkBlendMode mode) {
  46. switch (mode) {
  47. case SkBlendMode::kSrc:
  48. return src;
  49. case SkBlendMode::kDst:
  50. return dst;
  51. default: {
  52. SkPMColor4f pmS = src.premul();
  53. SkPMColor4f pmD = dst.premul();
  54. return SkBlendMode_Apply(mode, pmS, pmD).unpremul();
  55. }
  56. }
  57. }
  58. // Even with kEntirePaint_Bits, we always ensure that the master paint's
  59. // text-encoding is respected, since that controls how we interpret the
  60. // text/length parameters of a draw[Pos]Text call.
  61. void SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo(
  62. SkPaint* dst, const SkPaint& src, const LayerInfo& info) {
  63. SkColor4f srcColor = src.getColor4f();
  64. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  65. // The framework may respect the alpha value on the original paint.
  66. // Match this legacy behavior.
  67. if (src.getAlpha() == 255) {
  68. srcColor.fA = dst->getColor4f().fA;
  69. }
  70. #endif
  71. dst->setColor4f(xferColor(srcColor, dst->getColor4f(), (SkBlendMode)info.fColorMode),
  72. sk_srgb_singleton());
  73. BitFlags bits = info.fPaintBits;
  74. if (0 == bits) {
  75. return;
  76. }
  77. if (kEntirePaint_Bits == bits) {
  78. // we've already computed these, so save it from the assignment
  79. bool aa = dst->isAntiAlias();
  80. bool di = dst->isDither();
  81. SkColor4f c = dst->getColor4f();
  82. *dst = src;
  83. dst->setAntiAlias(aa);
  84. dst->setDither(di);
  85. dst->setColor4f(c, sk_srgb_singleton());
  86. return;
  87. }
  88. if (bits & kStyle_Bit) {
  89. dst->setStyle(src.getStyle());
  90. dst->setStrokeWidth(src.getStrokeWidth());
  91. dst->setStrokeMiter(src.getStrokeMiter());
  92. dst->setStrokeCap(src.getStrokeCap());
  93. dst->setStrokeJoin(src.getStrokeJoin());
  94. }
  95. if (bits & kPathEffect_Bit) {
  96. dst->setPathEffect(src.refPathEffect());
  97. }
  98. if (bits & kMaskFilter_Bit) {
  99. dst->setMaskFilter(src.refMaskFilter());
  100. }
  101. if (bits & kShader_Bit) {
  102. dst->setShader(src.refShader());
  103. }
  104. if (bits & kColorFilter_Bit) {
  105. dst->setColorFilter(src.refColorFilter());
  106. }
  107. if (bits & kXfermode_Bit) {
  108. dst->setBlendMode(src.getBlendMode());
  109. }
  110. // we don't override these
  111. #if 0
  112. dst->setTypeface(src.getTypeface());
  113. dst->setTextSize(src.getTextSize());
  114. dst->setTextScaleX(src.getTextScaleX());
  115. dst->setRasterizer(src.getRasterizer());
  116. dst->setLooper(src.getLooper());
  117. dst->setTextEncoding(src.getTextEncoding());
  118. dst->setHinting(src.getHinting());
  119. #endif
  120. }
  121. // Should we add this to canvas?
  122. static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
  123. SkMatrix m = canvas->getTotalMatrix();
  124. m.postTranslate(dx, dy);
  125. canvas->setMatrix(m);
  126. }
  127. SkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext(
  128. const SkLayerDrawLooper* looper) : fCurrRec(looper->fRecs) {}
  129. bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas,
  130. SkPaint* paint) {
  131. canvas->restore();
  132. if (nullptr == fCurrRec) {
  133. return false;
  134. }
  135. ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo);
  136. canvas->save();
  137. if (fCurrRec->fInfo.fPostTranslate) {
  138. postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
  139. fCurrRec->fInfo.fOffset.fY);
  140. } else {
  141. canvas->translate(fCurrRec->fInfo.fOffset.fX,
  142. fCurrRec->fInfo.fOffset.fY);
  143. }
  144. fCurrRec = fCurrRec->fNext;
  145. return true;
  146. }
  147. bool SkLayerDrawLooper::asABlurShadow(BlurShadowRec* bsRec) const {
  148. if (fCount != 2) {
  149. return false;
  150. }
  151. const Rec* rec = fRecs;
  152. // bottom layer needs to be just blur(maskfilter)
  153. if ((rec->fInfo.fPaintBits & ~kMaskFilter_Bit)) {
  154. return false;
  155. }
  156. if (SkBlendMode::kSrc != (SkBlendMode)rec->fInfo.fColorMode) {
  157. return false;
  158. }
  159. const SkMaskFilter* mf = rec->fPaint.getMaskFilter();
  160. if (nullptr == mf) {
  161. return false;
  162. }
  163. SkMaskFilterBase::BlurRec maskBlur;
  164. if (!as_MFB(mf)->asABlur(&maskBlur)) {
  165. return false;
  166. }
  167. rec = rec->fNext;
  168. // top layer needs to be "plain"
  169. if (rec->fInfo.fPaintBits) {
  170. return false;
  171. }
  172. if (SkBlendMode::kDst != (SkBlendMode)rec->fInfo.fColorMode) {
  173. return false;
  174. }
  175. if (!rec->fInfo.fOffset.equals(0, 0)) {
  176. return false;
  177. }
  178. if (bsRec) {
  179. bsRec->fSigma = maskBlur.fSigma;
  180. bsRec->fOffset = fRecs->fInfo.fOffset;
  181. // TODO: Update BlurShadowRec to use SkColor4f?
  182. bsRec->fColor = fRecs->fPaint.getColor();
  183. bsRec->fStyle = maskBlur.fStyle;
  184. }
  185. return true;
  186. }
  187. ///////////////////////////////////////////////////////////////////////////////
  188. void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const {
  189. buffer.writeInt(fCount);
  190. Rec* rec = fRecs;
  191. for (int i = 0; i < fCount; i++) {
  192. // Legacy "flagsmask" field -- now ignored, remove when we bump version
  193. buffer.writeInt(0);
  194. buffer.writeInt(rec->fInfo.fPaintBits);
  195. buffer.writeInt((int)rec->fInfo.fColorMode);
  196. buffer.writePoint(rec->fInfo.fOffset);
  197. buffer.writeBool(rec->fInfo.fPostTranslate);
  198. buffer.writePaint(rec->fPaint);
  199. rec = rec->fNext;
  200. }
  201. }
  202. sk_sp<SkFlattenable> SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) {
  203. int count = buffer.readInt();
  204. Builder builder;
  205. for (int i = 0; i < count; i++) {
  206. LayerInfo info;
  207. // Legacy "flagsmask" field -- now ignored, remove when we bump version
  208. (void)buffer.readInt();
  209. info.fPaintBits = buffer.readInt();
  210. info.fColorMode = (SkBlendMode)buffer.readInt();
  211. buffer.readPoint(&info.fOffset);
  212. info.fPostTranslate = buffer.readBool();
  213. buffer.readPaint(builder.addLayerOnTop(info), nullptr);
  214. if (!buffer.isValid()) {
  215. return nullptr;
  216. }
  217. }
  218. return builder.detach();
  219. }
  220. SkLayerDrawLooper::Builder::Builder()
  221. : fRecs(nullptr),
  222. fTopRec(nullptr),
  223. fCount(0) {
  224. }
  225. SkLayerDrawLooper::Builder::~Builder() {
  226. Rec* rec = fRecs;
  227. while (rec) {
  228. Rec* next = rec->fNext;
  229. delete rec;
  230. rec = next;
  231. }
  232. }
  233. SkPaint* SkLayerDrawLooper::Builder::addLayer(const LayerInfo& info) {
  234. fCount += 1;
  235. Rec* rec = new Rec;
  236. rec->fNext = fRecs;
  237. rec->fInfo = info;
  238. fRecs = rec;
  239. if (nullptr == fTopRec) {
  240. fTopRec = rec;
  241. }
  242. return &rec->fPaint;
  243. }
  244. void SkLayerDrawLooper::Builder::addLayer(SkScalar dx, SkScalar dy) {
  245. LayerInfo info;
  246. info.fOffset.set(dx, dy);
  247. (void)this->addLayer(info);
  248. }
  249. SkPaint* SkLayerDrawLooper::Builder::addLayerOnTop(const LayerInfo& info) {
  250. fCount += 1;
  251. Rec* rec = new Rec;
  252. rec->fNext = nullptr;
  253. rec->fInfo = info;
  254. if (nullptr == fRecs) {
  255. fRecs = rec;
  256. } else {
  257. SkASSERT(fTopRec);
  258. fTopRec->fNext = rec;
  259. }
  260. fTopRec = rec;
  261. return &rec->fPaint;
  262. }
  263. sk_sp<SkDrawLooper> SkLayerDrawLooper::Builder::detach() {
  264. SkLayerDrawLooper* looper = new SkLayerDrawLooper;
  265. looper->fCount = fCount;
  266. looper->fRecs = fRecs;
  267. fCount = 0;
  268. fRecs = nullptr;
  269. fTopRec = nullptr;
  270. return sk_sp<SkDrawLooper>(looper);
  271. }
  272. sk_sp<SkDrawLooper> SkBlurDrawLooper::Make(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy)
  273. {
  274. return Make(SkColor4f::FromColor(color), sk_srgb_singleton(), sigma, dx, dy);
  275. }
  276. sk_sp<SkDrawLooper> SkBlurDrawLooper::Make(SkColor4f color, SkColorSpace* cs,
  277. SkScalar sigma, SkScalar dx, SkScalar dy)
  278. {
  279. sk_sp<SkMaskFilter> blur = nullptr;
  280. if (sigma > 0.0f) {
  281. blur = SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma, true);
  282. }
  283. SkLayerDrawLooper::Builder builder;
  284. // First layer
  285. SkLayerDrawLooper::LayerInfo defaultLayer;
  286. builder.addLayer(defaultLayer);
  287. // Blur layer
  288. SkLayerDrawLooper::LayerInfo blurInfo;
  289. blurInfo.fColorMode = SkBlendMode::kSrc;
  290. blurInfo.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit;
  291. blurInfo.fOffset = SkVector::Make(dx, dy);
  292. SkPaint* paint = builder.addLayer(blurInfo);
  293. paint->setMaskFilter(std::move(blur));
  294. paint->setColor4f(color, cs);
  295. return builder.detach();
  296. }