OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2015 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 "SkPath.h" |
| 9 #include "SkRect.h" |
| 10 #include "SkRemote.h" |
| 11 |
| 12 namespace SkRemote { |
| 13 |
| 14 Misc Misc::CreateFrom(const SkPaint& paint) { |
| 15 Misc misc = { |
| 16 paint.getColor(), |
| 17 paint.getFilterQuality(), |
| 18 paint.isAntiAlias(), |
| 19 paint.isDither(), |
| 20 }; |
| 21 return misc; |
| 22 } |
| 23 |
| 24 void Misc::applyTo(SkPaint* paint) const { |
| 25 paint->setColor (fColor); |
| 26 paint->setFilterQuality(fFilterQuality); |
| 27 paint->setAntiAlias (fAntiAlias); |
| 28 paint->setDither (fDither); |
| 29 } |
| 30 |
| 31 static bool operator==(const Misc& a, const Misc& b) { |
| 32 return a.fColor == b.fColor |
| 33 && a.fFilterQuality == b.fFilterQuality |
| 34 && a.fAntiAlias == b.fAntiAlias |
| 35 && a.fDither == b.fDither; |
| 36 } |
| 37 |
| 38 Stroke Stroke::CreateFrom(const SkPaint& paint) { |
| 39 Stroke stroke = { |
| 40 paint.getStrokeWidth(), |
| 41 paint.getStrokeMiter(), |
| 42 paint.getStrokeCap(), |
| 43 paint.getStrokeJoin(), |
| 44 }; |
| 45 return stroke; |
| 46 } |
| 47 |
| 48 void Stroke::applyTo(SkPaint* paint) const { |
| 49 paint->setStrokeWidth(fWidth); |
| 50 paint->setStrokeMiter(fMiter); |
| 51 paint->setStrokeCap (fCap); |
| 52 paint->setStrokeJoin (fJoin); |
| 53 } |
| 54 |
| 55 static bool operator==(const Stroke& a, const Stroke& b) { |
| 56 return a.fWidth == b.fWidth |
| 57 && a.fMiter == b.fMiter |
| 58 && a.fCap == b.fCap |
| 59 && a.fJoin == b.fJoin; |
| 60 } |
| 61 |
| 62 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // |
| 63 |
| 64 Cache* Cache::CreateNeverCache() { |
| 65 struct NeverCache final : public Cache { |
| 66 NeverCache() |
| 67 : fNextMatrix(Type::kMatrix) |
| 68 , fNextMisc (Type::kMisc) |
| 69 , fNextPath (Type::kPath) |
| 70 , fNextStroke(Type::kStroke) |
| 71 {} |
| 72 void cleanup(Encoder*) override {} |
| 73 |
| 74 static bool Helper(ID* next, ID* id, LookupScope* ls) { |
| 75 *id = (*next)++; |
| 76 ls->undefineWhenDone(*id); |
| 77 return false; |
| 78 } |
| 79 |
| 80 bool lookup(const SkMatrix&, ID* id, LookupScope* ls) override { |
| 81 return Helper(&fNextMatrix, id, ls); |
| 82 } |
| 83 bool lookup(const Misc&, ID* id, LookupScope* ls) override { |
| 84 return Helper(&fNextMisc, id, ls); |
| 85 } |
| 86 bool lookup(const SkPath&, ID* id, LookupScope* ls) override { |
| 87 return Helper(&fNextPath, id, ls); |
| 88 } |
| 89 bool lookup(const Stroke&, ID* id, LookupScope* ls) override { |
| 90 return Helper(&fNextStroke, id, ls); |
| 91 } |
| 92 |
| 93 ID fNextMatrix, |
| 94 fNextMisc, |
| 95 fNextPath, |
| 96 fNextStroke; |
| 97 }; |
| 98 return new NeverCache; |
| 99 } |
| 100 |
| 101 // Can't be declared locally inside AlwaysCache because of the templating.
:( |
| 102 template <typename T, typename Map> |
| 103 static bool always_cache_helper(const T& val, Map* map, ID* next, ID* id) { |
| 104 if (ID* found = map->find(val)) { |
| 105 *id = *found; |
| 106 return true; |
| 107 } |
| 108 *id = (*next)++; |
| 109 map->set(val, *id); |
| 110 return false; |
| 111 } |
| 112 |
| 113 Cache* Cache::CreateAlwaysCache() { |
| 114 struct AlwaysCache final : public Cache { |
| 115 AlwaysCache() |
| 116 : fNextMatrix(Type::kMatrix) |
| 117 , fNextMisc (Type::kMisc) |
| 118 , fNextPath (Type::kPath) |
| 119 , fNextStroke(Type::kStroke) |
| 120 {} |
| 121 |
| 122 void cleanup(Encoder* encoder) override { |
| 123 fMatrix.foreach([=](const SkMatrix&, ID* id) { encoder->undefine
(*id); }); |
| 124 fMisc .foreach([=](const Misc&, ID* id) { encoder->undefine
(*id); }); |
| 125 fPath .foreach([=](const SkPath&, ID* id) { encoder->undefine
(*id); }); |
| 126 fStroke.foreach([=](const Stroke&, ID* id) { encoder->undefine
(*id); }); |
| 127 } |
| 128 |
| 129 |
| 130 bool lookup(const SkMatrix& matrix, ID* id, LookupScope*) override { |
| 131 return always_cache_helper(matrix, &fMatrix, &fNextMatrix, id); |
| 132 } |
| 133 bool lookup(const Misc& misc, ID* id, LookupScope*) override { |
| 134 return always_cache_helper(misc, &fMisc, &fNextMisc, id); |
| 135 } |
| 136 bool lookup(const SkPath& path, ID* id, LookupScope*) override { |
| 137 return always_cache_helper(path, &fPath, &fNextPath, id); |
| 138 } |
| 139 bool lookup(const Stroke& stroke, ID* id, LookupScope*) override { |
| 140 return always_cache_helper(stroke, &fStroke, &fNextStroke, id); |
| 141 } |
| 142 |
| 143 SkTHashMap<SkMatrix, ID> fMatrix; |
| 144 SkTHashMap<Misc, ID> fMisc; |
| 145 SkTHashMap<SkPath, ID> fPath; |
| 146 SkTHashMap<Stroke, ID> fStroke; |
| 147 ID fNextMatrix, |
| 148 fNextMisc, |
| 149 fNextPath, |
| 150 fNextStroke; |
| 151 }; |
| 152 return new AlwaysCache; |
| 153 } |
| 154 |
| 155 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // |
| 156 |
| 157 Client::Client(Cache* cache, Encoder* encoder) |
| 158 : SkCanvas(1,1) |
| 159 , fCache(cache) |
| 160 , fEncoder(encoder) |
| 161 {} |
| 162 |
| 163 Client::~Client() { |
| 164 fCache->cleanup(fEncoder); |
| 165 } |
| 166 |
| 167 template <typename T> |
| 168 ID LookupScope::lookup(const T& val) { |
| 169 ID id; |
| 170 if (!fCache->lookup(val, &id, this)) { |
| 171 fEncoder->define(id, val); |
| 172 } |
| 173 return id; |
| 174 } |
| 175 |
| 176 void Client::willSave() { fEncoder->save(); } |
| 177 void Client::didRestore() { fEncoder->restore(); } |
| 178 |
| 179 void Client::didConcat (const SkMatrix&) { this->didSetMatrix(this->getTot
alMatrix()); } |
| 180 void Client::didSetMatrix(const SkMatrix& matrix) { |
| 181 LookupScope ls(fCache, fEncoder); |
| 182 fEncoder->setMatrix(ls.lookup(matrix)); |
| 183 } |
| 184 |
| 185 void Client::onDrawOval(const SkRect& oval, const SkPaint& paint) { |
| 186 SkPath path; |
| 187 path.addOval(oval); |
| 188 this->onDrawPath(path, paint); |
| 189 } |
| 190 |
| 191 void Client::onDrawRect(const SkRect& rect, const SkPaint& paint) { |
| 192 SkPath path; |
| 193 path.addRect(rect); |
| 194 this->onDrawPath(path, paint); |
| 195 } |
| 196 |
| 197 void Client::onDrawPath(const SkPath& path, const SkPaint& paint) { |
| 198 LookupScope ls(fCache, fEncoder); |
| 199 ID p = ls.lookup(path), |
| 200 m = ls.lookup(Misc::CreateFrom(paint)); |
| 201 |
| 202 if (paint.getStyle() == SkPaint::kFill_Style) { |
| 203 fEncoder->fillPath(p, m); |
| 204 } else { |
| 205 // TODO: handle kStrokeAndFill_Style |
| 206 fEncoder->strokePath(p, m, ls.lookup(Stroke::CreateFrom(paint))); |
| 207 } |
| 208 } |
| 209 |
| 210 void Client::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle e
dgeStyle) { |
| 211 SkPath path; |
| 212 path.addRect(rect); |
| 213 this->onClipPath(path, op, edgeStyle); |
| 214 } |
| 215 |
| 216 void Client::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl
e edgeStyle) { |
| 217 SkPath path; |
| 218 path.addRRect(rrect); |
| 219 this->onClipPath(path, op, edgeStyle); |
| 220 } |
| 221 |
| 222 void Client::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle e
dgeStyle) { |
| 223 LookupScope ls(fCache, fEncoder); |
| 224 fEncoder->clipPath(ls.lookup(path), op, edgeStyle == kSoft_ClipEdgeStyle
); |
| 225 } |
| 226 |
| 227 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // |
| 228 |
| 229 Server::Server(SkCanvas* canvas) : fCanvas(canvas) {} |
| 230 |
| 231 void Server::define(ID id, const SkMatrix& v) { fMatrix.set(id, v); } |
| 232 void Server::define(ID id, const Misc& v) { fMisc .set(id, v); } |
| 233 void Server::define(ID id, const SkPath& v) { fPath .set(id, v); } |
| 234 void Server::define(ID id, const Stroke& v) { fStroke.set(id, v); } |
| 235 |
| 236 void Server::undefine(ID id) { |
| 237 switch(id.type()) { |
| 238 case Type::kMatrix: return fMatrix.remove(id); |
| 239 case Type::kMisc: return fMisc .remove(id); |
| 240 case Type::kPath: return fPath .remove(id); |
| 241 case Type::kStroke: return fStroke.remove(id); |
| 242 |
| 243 case Type::kNone: SkASSERT(false); |
| 244 }; |
| 245 } |
| 246 |
| 247 void Server:: save() { fCanvas->save(); } |
| 248 void Server::restore() { fCanvas->restore(); } |
| 249 |
| 250 void Server::setMatrix(ID matrix) { fCanvas->setMatrix(fMatrix.find(matrix))
; } |
| 251 |
| 252 void Server::clipPath(ID path, SkRegion::Op op, bool aa) { |
| 253 fCanvas->clipPath(fPath.find(path), op, aa); |
| 254 } |
| 255 void Server::fillPath(ID path, ID misc) { |
| 256 SkPaint paint; |
| 257 paint.setStyle(SkPaint::kFill_Style); |
| 258 fMisc.find(misc).applyTo(&paint); |
| 259 fCanvas->drawPath(fPath.find(path), paint); |
| 260 } |
| 261 void Server::strokePath(ID path, ID misc, ID stroke) { |
| 262 SkPaint paint; |
| 263 paint.setStyle(SkPaint::kStroke_Style); |
| 264 fMisc .find(misc ).applyTo(&paint); |
| 265 fStroke.find(stroke).applyTo(&paint); |
| 266 fCanvas->drawPath(fPath.find(path), paint); |
| 267 } |
| 268 |
| 269 } // namespace SkRemote |
OLD | NEW |