| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/effects/SkLayerRasterizer.cpp | |
| 2 ** | |
| 3 ** Copyright 2006, The Android Open Source Project | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 #include "SkLayerRasterizer.h" | |
| 19 #include "SkBuffer.h" | |
| 20 #include "SkDraw.h" | |
| 21 #include "SkMask.h" | |
| 22 #include "SkMaskFilter.h" | |
| 23 #include "SkPaint.h" | |
| 24 #include "SkPath.h" | |
| 25 #include "SkRegion.h" | |
| 26 #include "SkXfermode.h" | |
| 27 #include <new> | |
| 28 | |
| 29 struct SkLayerRasterizer_Rec { | |
| 30 SkPaint fPaint; | |
| 31 SkVector fOffset; | |
| 32 }; | |
| 33 | |
| 34 SkLayerRasterizer::SkLayerRasterizer() : fLayers(sizeof(SkLayerRasterizer_Rec)) | |
| 35 { | |
| 36 } | |
| 37 | |
| 38 SkLayerRasterizer::~SkLayerRasterizer() | |
| 39 { | |
| 40 SkDeque::Iter iter(fLayers); | |
| 41 SkLayerRasterizer_Rec* rec; | |
| 42 | |
| 43 while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) | |
| 44 rec->fPaint.~SkPaint(); | |
| 45 } | |
| 46 | |
| 47 void SkLayerRasterizer::addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy) | |
| 48 { | |
| 49 SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers.push_back(); | |
| 50 | |
| 51 new (&rec->fPaint) SkPaint(paint); | |
| 52 rec->fOffset.set(dx, dy); | |
| 53 } | |
| 54 | |
| 55 static bool compute_bounds(const SkDeque& layers, const SkPath& path, const SkMa
trix& matrix, | |
| 56 const SkIRect* clipBounds, SkIRect* bounds) | |
| 57 { | |
| 58 SkDeque::Iter iter(layers); | |
| 59 SkLayerRasterizer_Rec* rec; | |
| 60 | |
| 61 bounds->set(SK_MaxS32, SK_MaxS32, SK_MinS32, SK_MinS32); | |
| 62 | |
| 63 while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) | |
| 64 { | |
| 65 const SkPaint& paint = rec->fPaint; | |
| 66 SkPath fillPath, devPath; | |
| 67 const SkPath* p = &path; | |
| 68 | |
| 69 if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) | |
| 70 { | |
| 71 paint.getFillPath(path, &fillPath); | |
| 72 p = &fillPath; | |
| 73 } | |
| 74 if (p->isEmpty()) | |
| 75 continue; | |
| 76 | |
| 77 // apply the matrix and offset | |
| 78 { | |
| 79 SkMatrix m = matrix; | |
| 80 m.preTranslate(rec->fOffset.fX, rec->fOffset.fY); | |
| 81 p->transform(m, &devPath); | |
| 82 } | |
| 83 | |
| 84 SkMask mask; | |
| 85 if (!SkDraw::DrawToMask(devPath, clipBounds, paint.getMaskFilter(), &mat
rix, | |
| 86 &mask, SkMask::kJustComputeBounds_CreateMode)) | |
| 87 return false; | |
| 88 | |
| 89 bounds->join(mask.fBounds); | |
| 90 } | |
| 91 return true; | |
| 92 } | |
| 93 | |
| 94 bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, | |
| 95 const SkIRect* clipBounds, | |
| 96 SkMask* mask, SkMask::CreateMode mode) | |
| 97 { | |
| 98 if (fLayers.empty()) | |
| 99 return false; | |
| 100 | |
| 101 if (SkMask::kJustRenderImage_CreateMode != mode) | |
| 102 { | |
| 103 if (!compute_bounds(fLayers, path, matrix, clipBounds, &mask->fBounds)) | |
| 104 return false; | |
| 105 } | |
| 106 | |
| 107 if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) | |
| 108 { | |
| 109 mask->fFormat = SkMask::kA8_Format; | |
| 110 mask->fRowBytes = SkToU16(mask->fBounds.width()); | |
| 111 size_t size = mask->computeImageSize(); | |
| 112 if (0 == size) { | |
| 113 return false; // too big to allocate, abort | |
| 114 } | |
| 115 mask->fImage = SkMask::AllocImage(size); | |
| 116 memset(mask->fImage, 0, size); | |
| 117 } | |
| 118 | |
| 119 if (SkMask::kJustComputeBounds_CreateMode != mode) | |
| 120 { | |
| 121 SkBitmap device; | |
| 122 SkDraw draw; | |
| 123 SkMatrix translatedMatrix; // this translates us to our local pixels | |
| 124 SkMatrix drawMatrix; // this translates the path by each layer's
offset | |
| 125 SkRegion rectClip; | |
| 126 | |
| 127 rectClip.setRect(0, 0, mask->fBounds.width(), mask->fBounds.height()); | |
| 128 | |
| 129 translatedMatrix = matrix; | |
| 130 translatedMatrix.postTranslate(-SkIntToScalar(mask->fBounds.fLeft), | |
| 131 -SkIntToScalar(mask->fBounds.fTop)); | |
| 132 | |
| 133 device.setConfig(SkBitmap::kA8_Config, mask->fBounds.width(), mask->fBou
nds.height(), mask->fRowBytes); | |
| 134 device.setPixels(mask->fImage); | |
| 135 | |
| 136 draw.fBitmap = &device; | |
| 137 draw.fMatrix = &drawMatrix; | |
| 138 draw.fClip = &rectClip; | |
| 139 // we set the matrixproc in the loop, as the matrix changes each time (p
otentially) | |
| 140 draw.fBounder = NULL; | |
| 141 | |
| 142 SkDeque::Iter iter(fLayers); | |
| 143 SkLayerRasterizer_Rec* rec; | |
| 144 | |
| 145 while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) { | |
| 146 drawMatrix = translatedMatrix; | |
| 147 drawMatrix.preTranslate(rec->fOffset.fX, rec->fOffset.fY); | |
| 148 draw.drawPath(path, rec->fPaint); | |
| 149 } | |
| 150 } | |
| 151 return true; | |
| 152 } | |
| 153 | |
| 154 /////////// Routines for flattening ///////////////// | |
| 155 | |
| 156 static void paint_read(SkPaint* paint, SkFlattenableReadBuffer& buffer) | |
| 157 { | |
| 158 paint->setAntiAlias(buffer.readBool()); | |
| 159 paint->setStyle((SkPaint::Style)buffer.readU8()); | |
| 160 paint->setAlpha(buffer.readU8()); | |
| 161 | |
| 162 if (paint->getStyle() != SkPaint::kFill_Style) | |
| 163 { | |
| 164 paint->setStrokeWidth(buffer.readScalar()); | |
| 165 paint->setStrokeMiter(buffer.readScalar()); | |
| 166 paint->setStrokeCap((SkPaint::Cap)buffer.readU8()); | |
| 167 paint->setStrokeJoin((SkPaint::Join)buffer.readU8()); | |
| 168 } | |
| 169 | |
| 170 paint->setMaskFilter((SkMaskFilter*)buffer.readFlattenable())->safeUnref(); | |
| 171 paint->setPathEffect((SkPathEffect*)buffer.readFlattenable())->safeUnref(); | |
| 172 paint->setRasterizer((SkRasterizer*)buffer.readFlattenable())->safeUnref(); | |
| 173 paint->setXfermode((SkXfermode*)buffer.readFlattenable())->safeUnref(); | |
| 174 } | |
| 175 | |
| 176 static void paint_write(const SkPaint& paint, SkFlattenableWriteBuffer& buffer) | |
| 177 { | |
| 178 buffer.writeBool(paint.isAntiAlias()); | |
| 179 buffer.write8(paint.getStyle()); | |
| 180 buffer.write8(paint.getAlpha()); | |
| 181 | |
| 182 if (paint.getStyle() != SkPaint::kFill_Style) | |
| 183 { | |
| 184 buffer.writeScalar(paint.getStrokeWidth()); | |
| 185 buffer.writeScalar(paint.getStrokeMiter()); | |
| 186 buffer.write8(paint.getStrokeCap()); | |
| 187 buffer.write8(paint.getStrokeJoin()); | |
| 188 } | |
| 189 | |
| 190 buffer.writeFlattenable(paint.getMaskFilter()); | |
| 191 buffer.writeFlattenable(paint.getPathEffect()); | |
| 192 buffer.writeFlattenable(paint.getRasterizer()); | |
| 193 buffer.writeFlattenable(paint.getXfermode()); | |
| 194 } | |
| 195 | |
| 196 SkLayerRasterizer::SkLayerRasterizer(SkFlattenableReadBuffer& buffer) | |
| 197 : SkRasterizer(buffer), fLayers(sizeof(SkLayerRasterizer_Rec)) | |
| 198 { | |
| 199 int count = buffer.readS32(); | |
| 200 | |
| 201 for (int i = 0; i < count; i++) | |
| 202 { | |
| 203 SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers.push_back()
; | |
| 204 | |
| 205 #if 0 | |
| 206 new (&rec->fPaint) SkPaint(buffer); | |
| 207 #else | |
| 208 new (&rec->fPaint) SkPaint; | |
| 209 paint_read(&rec->fPaint, buffer); | |
| 210 #endif | |
| 211 rec->fOffset.fX = buffer.readScalar(); | |
| 212 rec->fOffset.fY = buffer.readScalar(); | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 void SkLayerRasterizer::flatten(SkFlattenableWriteBuffer& buffer) | |
| 217 { | |
| 218 this->INHERITED::flatten(buffer); | |
| 219 | |
| 220 buffer.write32(fLayers.count()); | |
| 221 | |
| 222 SkDeque::Iter iter(fLayers); | |
| 223 const SkLayerRasterizer_Rec* rec; | |
| 224 | |
| 225 while ((rec = (const SkLayerRasterizer_Rec*)iter.next()) != NULL) | |
| 226 { | |
| 227 #if 0 | |
| 228 rec->fPaint.flatten(buffer); | |
| 229 #else | |
| 230 paint_write(rec->fPaint, buffer); | |
| 231 #endif | |
| 232 buffer.writeScalar(rec->fOffset.fX); | |
| 233 buffer.writeScalar(rec->fOffset.fY); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 SkFlattenable* SkLayerRasterizer::CreateProc(SkFlattenableReadBuffer& buffer) | |
| 238 { | |
| 239 return SkNEW_ARGS(SkLayerRasterizer, (buffer)); | |
| 240 } | |
| 241 | |
| 242 SkFlattenable::Factory SkLayerRasterizer::getFactory() | |
| 243 { | |
| 244 return CreateProc; | |
| 245 } | |
| 246 | |
| OLD | NEW |