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 "SkObjectParser.h" 9 #include "SkData.h" 10 #include "SkFontDescriptor.h" 11 #include "SkImage.h" 12 #include "SkPath.h" 13 #include "SkRRect.h" 14 #include "SkShader.h" 15 #include "SkStream.h" 16 #include "SkStringUtils.h" 17 #include "SkTypeface.h" 18 #include "SkUtils.h" 19 #include "SkClipOpPriv.h" 20 21 /* TODO(chudy): Replace all std::strings with char */ 22 23 SkString* SkObjectParser::BitmapToString(const SkBitmap& bitmap) { 24 SkString* mBitmap = new SkString("SkBitmap: "); 25 mBitmap->append("W: "); 26 mBitmap->appendS32(bitmap.width()); 27 mBitmap->append(" H: "); 28 mBitmap->appendS32(bitmap.height()); 29 30 const char* gColorTypeStrings[] = { 31 "None", "A8", "565", "4444", "RGBA", "BGRA", 32 "G8", "RGBAf16" 33 }; 34 static_assert(kLastEnum_SkColorType + 1 == SK_ARRAY_COUNT(gColorTypeStrings), 35 "colortype names do not match colortype enum"); 36 37 mBitmap->append(" ColorType: "); 38 mBitmap->append(gColorTypeStrings[bitmap.colorType()]); 39 40 if (bitmap.isOpaque()) { 41 mBitmap->append(" opaque"); 42 } else { 43 mBitmap->append(" not-opaque"); 44 } 45 46 if (bitmap.isImmutable()) { 47 mBitmap->append(" immutable"); 48 } else { 49 mBitmap->append(" not-immutable"); 50 } 51 52 if (bitmap.isVolatile()) { 53 mBitmap->append(" volatile"); 54 } else { 55 mBitmap->append(" not-volatile"); 56 } 57 58 mBitmap->append(" genID: "); 59 mBitmap->appendS32(bitmap.getGenerationID()); 60 61 return mBitmap; 62 } 63 64 SkString* SkObjectParser::ImageToString(const SkImage* image) { 65 SkString* str = new SkString("SkImage: "); 66 if (!image) { 67 return str; 68 } 69 70 str->append("W: "); 71 str->appendS32(image->width()); 72 str->append(" H: "); 73 str->appendS32(image->height()); 74 75 if (image->isOpaque()) { 76 str->append(" opaque"); 77 } else { 78 str->append(" not-opaque"); 79 } 80 81 str->append(" uniqueID: "); 82 str->appendS32(image->uniqueID()); 83 84 return str; 85 } 86 87 SkString* SkObjectParser::BoolToString(bool doAA) { 88 SkString* mBool = new SkString("Bool doAA: "); 89 if (doAA) { 90 mBool->append("True"); 91 } else { 92 mBool->append("False"); 93 } 94 return mBool; 95 } 96 97 SkString* SkObjectParser::CustomTextToString(const char* text) { 98 SkString* mText = new SkString(text); 99 return mText; 100 } 101 102 SkString* SkObjectParser::IntToString(int x, const char* text) { 103 SkString* mInt = new SkString(text); 104 mInt->append(" "); 105 mInt->appendScalar(SkIntToScalar(x)); 106 return mInt; 107 } 108 109 SkString* SkObjectParser::IRectToString(const SkIRect& rect) { 110 SkString* mRect = new SkString("SkIRect: "); 111 mRect->append("L: "); 112 mRect->appendS32(rect.left()); 113 mRect->append(", T: "); 114 mRect->appendS32(rect.top()); 115 mRect->append(", R: "); 116 mRect->appendS32(rect.right()); 117 mRect->append(", B: "); 118 mRect->appendS32(rect.bottom()); 119 return mRect; 120 } 121 122 SkString* SkObjectParser::MatrixToString(const SkMatrix& matrix) { 123 SkString* str = new SkString("SkMatrix: "); 124 #ifndef SK_IGNORE_TO_STRING 125 matrix.toString(str); 126 #endif 127 return str; 128 } 129 130 SkString* SkObjectParser::PaintToString(const SkPaint& paint) { 131 SkString* str = new SkString; 132 #ifndef SK_IGNORE_TO_STRING 133 paint.toString(str); 134 #endif 135 return str; 136 } 137 138 SkString* SkObjectParser::PathToString(const SkPath& path) { 139 SkString* mPath = new SkString; 140 141 mPath->appendf("Path (%d) (", path.getGenerationID()); 142 143 static const char* gFillStrings[] = { 144 "Winding", "EvenOdd", "InverseWinding", "InverseEvenOdd" 145 }; 146 147 mPath->append(gFillStrings[path.getFillType()]); 148 mPath->append(", "); 149 150 static const char* gConvexityStrings[] = { 151 "Unknown", "Convex", "Concave" 152 }; 153 SkASSERT(SkPath::kConcave_Convexity == 2); 154 155 mPath->append(gConvexityStrings[path.getConvexity()]); 156 mPath->append(", "); 157 158 if (path.isRect(nullptr)) { 159 mPath->append("isRect, "); 160 } else { 161 mPath->append("isNotRect, "); 162 } 163 164 if (path.isOval(nullptr)) { 165 mPath->append("isOval, "); 166 } else { 167 mPath->append("isNotOval, "); 168 } 169 170 SkRRect rrect; 171 if (path.isRRect(&rrect)) { 172 mPath->append("isRRect, "); 173 } else { 174 mPath->append("isNotRRect, "); 175 } 176 177 mPath->appendS32(path.countVerbs()); 178 mPath->append("V, "); 179 mPath->appendS32(path.countPoints()); 180 mPath->append("P): "); 181 182 static const char* gVerbStrings[] = { 183 "Move", "Line", "Quad", "Conic", "Cubic", "Close", "Done" 184 }; 185 static const int gPtsPerVerb[] = { 1, 1, 2, 2, 3, 0, 0 }; 186 static const int gPtOffsetPerVerb[] = { 0, 1, 1, 1, 1, 0, 0 }; 187 SkASSERT(SkPath::kDone_Verb == 6); 188 189 SkPath::Iter iter(const_cast<SkPath&>(path), false); 190 SkPath::Verb verb; 191 SkPoint points[4]; 192 193 for(verb = iter.next(points, false); 194 verb != SkPath::kDone_Verb; 195 verb = iter.next(points, false)) { 196 197 mPath->append(gVerbStrings[verb]); 198 mPath->append(" "); 199 200 for (int i = 0; i < gPtsPerVerb[verb]; ++i) { 201 mPath->append("("); 202 mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fX); 203 mPath->append(", "); 204 mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fY); 205 mPath->append(")"); 206 } 207 208 if (SkPath::kConic_Verb == verb) { 209 mPath->append("("); 210 mPath->appendScalar(iter.conicWeight()); 211 mPath->append(")"); 212 } 213 214 mPath->append(" "); 215 } 216 217 SkString* boundStr = SkObjectParser::RectToString(path.getBounds(), " Bound: "); 218 219 if (boundStr) { 220 mPath->append(*boundStr); 221 delete boundStr; 222 } 223 224 return mPath; 225 } 226 227 SkString* SkObjectParser::PointsToString(const SkPoint pts[], size_t count) { 228 SkString* mPoints = new SkString("SkPoints pts[]: "); 229 for (unsigned int i = 0; i < count; i++) { 230 mPoints->append("("); 231 mPoints->appendScalar(pts[i].fX); 232 mPoints->append(","); 233 mPoints->appendScalar(pts[i].fY); 234 mPoints->append(")"); 235 } 236 return mPoints; 237 } 238 239 SkString* SkObjectParser::PointModeToString(SkCanvas::PointMode mode) { 240 SkString* mMode = new SkString("SkCanvas::PointMode: "); 241 if (mode == SkCanvas::kPoints_PointMode) { 242 mMode->append("kPoints_PointMode"); 243 } else if (mode == SkCanvas::kLines_PointMode) { 244 mMode->append("kLines_Mode"); 245 } else if (mode == SkCanvas::kPolygon_PointMode) { 246 mMode->append("kPolygon_PointMode"); 247 } 248 return mMode; 249 } 250 251 SkString* SkObjectParser::RectToString(const SkRect& rect, const char* title) { 252 253 SkString* mRect = new SkString; 254 255 if (nullptr == title) { 256 mRect->append("SkRect: "); 257 } else { 258 mRect->append(title); 259 } 260 mRect->append("("); 261 mRect->appendScalar(rect.left()); 262 mRect->append(", "); 263 mRect->appendScalar(rect.top()); 264 mRect->append(", "); 265 mRect->appendScalar(rect.right()); 266 mRect->append(", "); 267 mRect->appendScalar(rect.bottom()); 268 mRect->append(")"); 269 return mRect; 270 } 271 272 SkString* SkObjectParser::RRectToString(const SkRRect& rrect, const char* title) { 273 274 SkString* mRRect = new SkString; 275 276 if (nullptr == title) { 277 mRRect->append("SkRRect ("); 278 if (rrect.isEmpty()) { 279 mRRect->append("empty"); 280 } else if (rrect.isRect()) { 281 mRRect->append("rect"); 282 } else if (rrect.isOval()) { 283 mRRect->append("oval"); 284 } else if (rrect.isSimple()) { 285 mRRect->append("simple"); 286 } else if (rrect.isNinePatch()) { 287 mRRect->append("nine-patch"); 288 } else { 289 SkASSERT(rrect.isComplex()); 290 mRRect->append("complex"); 291 } 292 mRRect->append("): "); 293 } else { 294 mRRect->append(title); 295 } 296 mRRect->append("("); 297 mRRect->appendScalar(rrect.rect().left()); 298 mRRect->append(", "); 299 mRRect->appendScalar(rrect.rect().top()); 300 mRRect->append(", "); 301 mRRect->appendScalar(rrect.rect().right()); 302 mRRect->append(", "); 303 mRRect->appendScalar(rrect.rect().bottom()); 304 mRRect->append(") radii: ("); 305 for (int i = 0; i < 4; ++i) { 306 const SkVector& radii = rrect.radii((SkRRect::Corner) i); 307 mRRect->appendScalar(radii.fX); 308 mRRect->append(", "); 309 mRRect->appendScalar(radii.fY); 310 if (i < 3) { 311 mRRect->append(", "); 312 } 313 } 314 mRRect->append(")"); 315 return mRRect; 316 } 317 318 SkString* SkObjectParser::ClipOpToString(SkClipOp op) { 319 SkString* mOp = new SkString("SkRegion::Op: "); 320 if (op == kDifference_SkClipOp) { 321 mOp->append("kDifference_Op"); 322 } else if (op == kIntersect_SkClipOp) { 323 mOp->append("kIntersect_Op"); 324 } else if (op == kUnion_SkClipOp) { 325 mOp->append("kUnion_Op"); 326 } else if (op == kXOR_SkClipOp) { 327 mOp->append("kXOR_Op"); 328 } else if (op == kReverseDifference_SkClipOp) { 329 mOp->append("kReverseDifference_Op"); 330 } else if (op == kReplace_SkClipOp) { 331 mOp->append("kReplace_Op"); 332 } else { 333 mOp->append("Unknown Type"); 334 } 335 return mOp; 336 } 337 338 SkString* SkObjectParser::RegionToString(const SkRegion& region) { 339 SkString* mRegion = new SkString("SkRegion: Data unavailable."); 340 return mRegion; 341 } 342 343 SkString* SkObjectParser::SaveLayerFlagsToString(SkCanvas::SaveLayerFlags saveLayerFlags) { 344 SkString* mFlags = new SkString("SkCanvas::SaveFlags: "); 345 if (saveLayerFlags & SkCanvas::kIsOpaque_SaveLayerFlag) { 346 mFlags->append("kIsOpaque_SaveLayerFlag "); 347 } 348 if (saveLayerFlags & SkCanvas::kPreserveLCDText_SaveLayerFlag) { 349 mFlags->append("kPreserveLCDText_SaveLayerFlag "); 350 } 351 return mFlags; 352 } 353 354 SkString* SkObjectParser::ScalarToString(SkScalar x, const char* text) { 355 SkString* mScalar = new SkString(text); 356 mScalar->append(" "); 357 mScalar->appendScalar(x); 358 return mScalar; 359 } 360 361 SkString* SkObjectParser::TextToString(const void* text, size_t byteLength, 362 SkPaint::TextEncoding encoding) { 363 364 SkString* decodedText = new SkString(); 365 switch (encoding) { 366 case SkPaint::kUTF8_TextEncoding: { 367 decodedText->append("UTF-8: "); 368 decodedText->append((const char*)text, byteLength); 369 break; 370 } 371 case SkPaint::kUTF16_TextEncoding: { 372 decodedText->append("UTF-16: "); 373 size_t sizeNeeded = SkUTF16_ToUTF8((uint16_t*)text, 374 SkToS32(byteLength / 2), 375 nullptr); 376 SkAutoSTMalloc<0x100, char> utf8(sizeNeeded); 377 SkUTF16_ToUTF8((uint16_t*)text, SkToS32(byteLength / 2), utf8); 378 decodedText->append(utf8, sizeNeeded); 379 break; 380 } 381 case SkPaint::kUTF32_TextEncoding: { 382 decodedText->append("UTF-32: "); 383 const SkUnichar* begin = (const SkUnichar*)text; 384 const SkUnichar* end = (const SkUnichar*)((const char*)text + byteLength); 385 for (const SkUnichar* unichar = begin; unichar < end; ++unichar) { 386 decodedText->appendUnichar(*unichar); 387 } 388 break; 389 } 390 case SkPaint::kGlyphID_TextEncoding: { 391 decodedText->append("GlyphID: "); 392 const uint16_t* begin = (const uint16_t*)text; 393 const uint16_t* end = (const uint16_t*)((const char*)text + byteLength); 394 for (const uint16_t* glyph = begin; glyph < end; ++glyph) { 395 decodedText->append("0x"); 396 decodedText->appendHex(*glyph); 397 decodedText->append(" "); 398 } 399 break; 400 } 401 default: 402 decodedText->append("Unknown text encoding."); 403 break; 404 } 405 406 return decodedText; 407 } 408 409 SkString* SkObjectParser::LatticeToString(const SkCanvas::Lattice& lattice) { 410 SkString* mLattice = new SkString; 411 mLattice->append("Lattice: "); 412 mLattice->append("(X: "); 413 mLattice->appendS32(lattice.fXCount); 414 mLattice->append(", Y:"); 415 mLattice->appendS32(lattice.fYCount); 416 mLattice->append(", Bounds:"); 417 if (nullptr != lattice.fBounds) { 418 mLattice->append(*IRectToString(*lattice.fBounds)); 419 } else { 420 mLattice->append("null"); 421 } 422 mLattice->append(")"); 423 return mLattice; 424 } 425