SkObjectParser.cpp revision f338d7c860bf0bca82cac793069522311a3dbb1a
17269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 27269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez/* 37269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez * Copyright 2012 Google Inc. 47269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez * 57269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez * Use of this source code is governed by a BSD-style license that can be 67269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez * found in the LICENSE file. 77269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez */ 87269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 97269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkObjectParser.h" 107269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkData.h" 117269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkFontDescriptor.h" 127269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkRRect.h" 137269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkShader.h" 147269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkStream.h" 157269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkStringUtils.h" 167269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkTypeface.h" 177269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez#include "SkUtils.h" 187269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 197269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez/* TODO(chudy): Replace all std::strings with char */ 207269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 217269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco JerezSkString* SkObjectParser::BitmapToString(const SkBitmap& bitmap) { 227269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez SkString* mBitmap = new SkString("SkBitmap: "); 237269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBitmap->append("W: "); 247269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBitmap->appendS32(bitmap.width()); 257269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBitmap->append(" H: "); 267269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBitmap->appendS32(bitmap.height()); 277269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 287269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez const char* gConfigStrings[] = { 2969f54d2a7e06210f28b46d20f74a906d9750a36eViktor Novotný "None", "A8", "Index8", "RGB565", "ARGB4444", "ARGB8888" 307269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez }; 317269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez SkASSERT(SkBitmap::kConfigCount == SK_ARRAY_COUNT(gConfigStrings)); 327269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 337269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBitmap->append(" Config: "); 34f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg mBitmap->append(gConfigStrings[bitmap.config()]); 357269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 367269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez if (bitmap.isOpaque()) { 372e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs mBitmap->append(" opaque"); 387269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez } else { 397269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBitmap->append(" not-opaque"); 407269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez } 417269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 422e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs if (bitmap.isImmutable()) { 432e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs mBitmap->append(" immutable"); 442e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs } else { 452e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs mBitmap->append(" not-immutable"); 462e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs } 472e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs 482e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs if (bitmap.isVolatile()) { 492e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs mBitmap->append(" volatile"); 502e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs } else { 512e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs mBitmap->append(" not-volatile"); 527269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez } 537269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 547269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBitmap->append(" genID: "); 557269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBitmap->appendS32(bitmap.getGenerationID()); 567269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez 57f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg return mBitmap; 587269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez} 592e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs 607269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco JerezSkString* SkObjectParser::BoolToString(bool doAA) { 617269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez SkString* mBool = new SkString("Bool doAA: "); 627269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez if (doAA) { 637269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez mBool->append("True"); 647269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez } else { 652e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs mBool->append("False"); 662e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs } 672e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs return mBool; 687269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez} 692e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs 702e47d01c9e5325906cf3bb979279599991c6328eBen SkeggsSkString* SkObjectParser::CustomTextToString(const char* text) { 717269a30b86745a29bb575ce3545ab82e6514ce2aFrancisco Jerez SkString* mText = new SkString(text); 72 return mText; 73} 74 75SkString* SkObjectParser::IntToString(int x, const char* text) { 76 SkString* mInt = new SkString(text); 77 mInt->append(" "); 78 mInt->appendScalar(SkIntToScalar(x)); 79 return mInt; 80} 81 82SkString* SkObjectParser::IRectToString(const SkIRect& rect) { 83 SkString* mRect = new SkString("SkIRect: "); 84 mRect->append("L: "); 85 mRect->appendS32(rect.left()); 86 mRect->append(", T: "); 87 mRect->appendS32(rect.top()); 88 mRect->append(", R: "); 89 mRect->appendS32(rect.right()); 90 mRect->append(", B: "); 91 mRect->appendS32(rect.bottom()); 92 return mRect; 93} 94 95SkString* SkObjectParser::MatrixToString(const SkMatrix& matrix) { 96 SkString* str = new SkString("SkMatrix: "); 97#ifndef SK_IGNORE_TO_STRING 98 matrix.toString(str); 99#endif 100 return str; 101} 102 103SkString* SkObjectParser::PaintToString(const SkPaint& paint) { 104 SkString* str = new SkString; 105#ifndef SK_IGNORE_TO_STRING 106 paint.toString(str); 107#endif 108 return str; 109} 110 111SkString* SkObjectParser::PathToString(const SkPath& path) { 112 SkString* mPath = new SkString("Path ("); 113 114 static const char* gFillStrings[] = { 115 "Winding", "EvenOdd", "InverseWinding", "InverseEvenOdd" 116 }; 117 118 mPath->append(gFillStrings[path.getFillType()]); 119 mPath->append(", "); 120 121 static const char* gConvexityStrings[] = { 122 "Unknown", "Convex", "Concave" 123 }; 124 SkASSERT(SkPath::kConcave_Convexity == 2); 125 126 mPath->append(gConvexityStrings[path.getConvexity()]); 127 mPath->append(", "); 128 129 if (path.isRect(NULL)) { 130 mPath->append("isRect, "); 131 } else { 132 mPath->append("isNotRect, "); 133 } 134 135 mPath->appendS32(path.countVerbs()); 136 mPath->append("V, "); 137 mPath->appendS32(path.countPoints()); 138 mPath->append("P): "); 139 140 static const char* gVerbStrings[] = { 141 "Move", "Line", "Quad", "Conic", "Cubic", "Close", "Done" 142 }; 143 static const int gPtsPerVerb[] = { 1, 1, 2, 2, 3, 0, 0 }; 144 static const int gPtOffsetPerVerb[] = { 0, 1, 1, 1, 1, 0, 0 }; 145 SkASSERT(SkPath::kDone_Verb == 6); 146 147 SkPath::Iter iter(const_cast<SkPath&>(path), false); 148 SkPath::Verb verb; 149 SkPoint points[4]; 150 151 for(verb = iter.next(points, false); 152 verb != SkPath::kDone_Verb; 153 verb = iter.next(points, false)) { 154 155 mPath->append(gVerbStrings[verb]); 156 mPath->append(" "); 157 158 for (int i = 0; i < gPtsPerVerb[verb]; ++i) { 159 mPath->append("("); 160 mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fX); 161 mPath->append(", "); 162 mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fY); 163 mPath->append(")"); 164 } 165 166 if (SkPath::kConic_Verb == verb) { 167 mPath->append("("); 168 mPath->appendScalar(iter.conicWeight()); 169 mPath->append(")"); 170 } 171 172 mPath->append(" "); 173 } 174 175 SkString* boundStr = SkObjectParser::RectToString(path.getBounds(), " Bound: "); 176 177 if (NULL != boundStr) { 178 mPath->append(*boundStr); 179 SkDELETE(boundStr); 180 } 181 182 return mPath; 183} 184 185SkString* SkObjectParser::PointsToString(const SkPoint pts[], size_t count) { 186 SkString* mPoints = new SkString("SkPoints pts[]: "); 187 for (unsigned int i = 0; i < count; i++) { 188 mPoints->append("("); 189 mPoints->appendScalar(pts[i].fX); 190 mPoints->append(","); 191 mPoints->appendScalar(pts[i].fY); 192 mPoints->append(")"); 193 } 194 return mPoints; 195} 196 197SkString* SkObjectParser::PointModeToString(SkCanvas::PointMode mode) { 198 SkString* mMode = new SkString("SkCanvas::PointMode: "); 199 if (mode == SkCanvas::kPoints_PointMode) { 200 mMode->append("kPoints_PointMode"); 201 } else if (mode == SkCanvas::kLines_PointMode) { 202 mMode->append("kLines_Mode"); 203 } else if (mode == SkCanvas::kPolygon_PointMode) { 204 mMode->append("kPolygon_PointMode"); 205 } 206 return mMode; 207} 208 209SkString* SkObjectParser::RectToString(const SkRect& rect, const char* title) { 210 211 SkString* mRect = new SkString; 212 213 if (NULL == title) { 214 mRect->append("SkRect: "); 215 } else { 216 mRect->append(title); 217 } 218 mRect->append("("); 219 mRect->appendScalar(rect.left()); 220 mRect->append(", "); 221 mRect->appendScalar(rect.top()); 222 mRect->append(", "); 223 mRect->appendScalar(rect.right()); 224 mRect->append(", "); 225 mRect->appendScalar(rect.bottom()); 226 mRect->append(")"); 227 return mRect; 228} 229 230SkString* SkObjectParser::RRectToString(const SkRRect& rrect, const char* title) { 231 232 SkString* mRRect = new SkString; 233 234 if (NULL == title) { 235 mRRect->append("SkRRect ("); 236 if (rrect.isEmpty()) { 237 mRRect->append("empty"); 238 } else if (rrect.isRect()) { 239 mRRect->append("rect"); 240 } else if (rrect.isOval()) { 241 mRRect->append("oval"); 242 } else if (rrect.isSimple()) { 243 mRRect->append("simple"); 244 } else if (rrect.isNinePatch()) { 245 mRRect->append("nine-patch"); 246 } else { 247 SkASSERT(rrect.isComplex()); 248 mRRect->append("complex"); 249 } 250 mRRect->append("): "); 251 } else { 252 mRRect->append(title); 253 } 254 mRRect->append("("); 255 mRRect->appendScalar(rrect.rect().left()); 256 mRRect->append(", "); 257 mRRect->appendScalar(rrect.rect().top()); 258 mRRect->append(", "); 259 mRRect->appendScalar(rrect.rect().right()); 260 mRRect->append(", "); 261 mRRect->appendScalar(rrect.rect().bottom()); 262 mRRect->append(") radii: ("); 263 for (int i = 0; i < 4; ++i) { 264 const SkVector& radii = rrect.radii((SkRRect::Corner) i); 265 mRRect->appendScalar(radii.fX); 266 mRRect->append(", "); 267 mRRect->appendScalar(radii.fY); 268 if (i < 3) { 269 mRRect->append(", "); 270 } 271 } 272 mRRect->append(")"); 273 return mRRect; 274} 275 276SkString* SkObjectParser::RegionOpToString(SkRegion::Op op) { 277 SkString* mOp = new SkString("SkRegion::Op: "); 278 if (op == SkRegion::kDifference_Op) { 279 mOp->append("kDifference_Op"); 280 } else if (op == SkRegion::kIntersect_Op) { 281 mOp->append("kIntersect_Op"); 282 } else if (op == SkRegion::kUnion_Op) { 283 mOp->append("kUnion_Op"); 284 } else if (op == SkRegion::kXOR_Op) { 285 mOp->append("kXOR_Op"); 286 } else if (op == SkRegion::kReverseDifference_Op) { 287 mOp->append("kReverseDifference_Op"); 288 } else if (op == SkRegion::kReplace_Op) { 289 mOp->append("kReplace_Op"); 290 } else { 291 mOp->append("Unknown Type"); 292 } 293 return mOp; 294} 295 296SkString* SkObjectParser::RegionToString(const SkRegion& region) { 297 SkString* mRegion = new SkString("SkRegion: Data unavailable."); 298 return mRegion; 299} 300 301SkString* SkObjectParser::SaveFlagsToString(SkCanvas::SaveFlags flags) { 302 SkString* mFlags = new SkString("SkCanvas::SaveFlags: "); 303 if (flags & SkCanvas::kMatrix_SaveFlag) { 304 mFlags->append("kMatrix_SaveFlag "); 305 } 306 if (flags & SkCanvas::kClip_SaveFlag) { 307 mFlags->append("kClip_SaveFlag "); 308 } 309 if (flags & SkCanvas::kHasAlphaLayer_SaveFlag) { 310 mFlags->append("kHasAlphaLayer_SaveFlag "); 311 } 312 if (flags & SkCanvas::kFullColorLayer_SaveFlag) { 313 mFlags->append("kFullColorLayer_SaveFlag "); 314 } 315 if (flags & SkCanvas::kClipToLayer_SaveFlag) { 316 mFlags->append("kClipToLayer_SaveFlag "); 317 } 318 return mFlags; 319} 320 321SkString* SkObjectParser::ScalarToString(SkScalar x, const char* text) { 322 SkString* mScalar = new SkString(text); 323 mScalar->append(" "); 324 mScalar->appendScalar(x); 325 return mScalar; 326} 327 328SkString* SkObjectParser::TextToString(const void* text, size_t byteLength, 329 SkPaint::TextEncoding encoding) { 330 331 SkString* decodedText = new SkString(); 332 switch (encoding) { 333 case SkPaint::kUTF8_TextEncoding: { 334 decodedText->append("UTF-8: "); 335 decodedText->append((const char*)text, byteLength); 336 break; 337 } 338 case SkPaint::kUTF16_TextEncoding: { 339 decodedText->append("UTF-16: "); 340 size_t sizeNeeded = SkUTF16_ToUTF8((uint16_t*)text, 341 SkToS32(byteLength / 2), 342 NULL); 343 SkAutoSTMalloc<0x100, char> utf8(sizeNeeded); 344 SkUTF16_ToUTF8((uint16_t*)text, SkToS32(byteLength / 2), utf8); 345 decodedText->append(utf8, sizeNeeded); 346 break; 347 } 348 case SkPaint::kUTF32_TextEncoding: { 349 decodedText->append("UTF-32: "); 350 const SkUnichar* begin = (const SkUnichar*)text; 351 const SkUnichar* end = (const SkUnichar*)((const char*)text + byteLength); 352 for (const SkUnichar* unichar = begin; unichar < end; ++unichar) { 353 decodedText->appendUnichar(*unichar); 354 } 355 break; 356 } 357 case SkPaint::kGlyphID_TextEncoding: { 358 decodedText->append("GlyphID: "); 359 const uint16_t* begin = (const uint16_t*)text; 360 const uint16_t* end = (const uint16_t*)((const char*)text + byteLength); 361 for (const uint16_t* glyph = begin; glyph < end; ++glyph) { 362 decodedText->append("0x"); 363 decodedText->appendHex(*glyph); 364 decodedText->append(" "); 365 } 366 break; 367 } 368 default: 369 decodedText->append("Unknown text encoding."); 370 break; 371 } 372 373 return decodedText; 374} 375