1902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com/*
2902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com * Copyright 2012 Google Inc.
3902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com *
4902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com * Use of this source code is governed by a BSD-style license that can be
5902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com * found in the LICENSE file.
6902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com */
7902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
8902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "SkObjectParser.h"
94991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#include "SkData.h"
104991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#include "SkFontDescriptor.h"
1180af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips#include "SkImage.h"
12d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkPath.h"
1367baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com#include "SkRRect.h"
1476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#include "SkShader.h"
15f515ffc3d44975a09755276e572448061df3e2fehumper@google.com#include "SkStream.h"
164991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#include "SkStringUtils.h"
174991b8f23482afc1494fd17647421ce68de53331robertphillips@google.com#include "SkTypeface.h"
18428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com#include "SkUtils.h"
19ebfce6d9b42198e04288a15953f40c395a7b6139Mike Reed#include "SkClipOpPriv.h"
20902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
21902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com/* TODO(chudy): Replace all std::strings with char */
22902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
2397cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::BitmapToString(const SkBitmap& bitmap) {
24195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    SkString* mBitmap = new SkString("SkBitmap: ");
25195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mBitmap->append("W: ");
26195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mBitmap->appendS32(bitmap.width());
27195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mBitmap->append(" H: ");
28195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mBitmap->appendS32(bitmap.height());
299d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
30c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    const char* gColorTypeStrings[] = {
3150a8dd0a00538840e55233146cb202e256cc6c34ethannicholas        "None", "A8", "565", "4444", "RGBA", "BGRA", "Index8", "G8", "RGBAf16"
32195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    };
3350a8dd0a00538840e55233146cb202e256cc6c34ethannicholas    static_assert(kLastEnum_SkColorType + 1 == SK_ARRAY_COUNT(gColorTypeStrings),
3450a8dd0a00538840e55233146cb202e256cc6c34ethannicholas                  "colortype names do not match colortype enum");
35195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com
36c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    mBitmap->append(" ColorType: ");
37c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    mBitmap->append(gColorTypeStrings[bitmap.colorType()]);
38195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com
39195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    if (bitmap.isOpaque()) {
40195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com        mBitmap->append(" opaque");
41195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    } else {
42195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com        mBitmap->append(" not-opaque");
43195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    }
44195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com
45195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    if (bitmap.isImmutable()) {
46195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com        mBitmap->append(" immutable");
47195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    } else {
48195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com        mBitmap->append(" not-immutable");
49195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    }
50195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com
51195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    if (bitmap.isVolatile()) {
52195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com        mBitmap->append(" volatile");
53195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    } else {
54195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com        mBitmap->append(" not-volatile");
55195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    }
56195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com
57195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mBitmap->append(" genID: ");
58195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mBitmap->appendS32(bitmap.getGenerationID());
59195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com
60902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    return mBitmap;
61902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
62902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
6380af64519b9ba9bbbf07feb8d72968460bfa1422robertphillipsSkString* SkObjectParser::ImageToString(const SkImage* image) {
6480af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    SkString* str = new SkString("SkImage: ");
6580af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    if (!image) {
6680af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips        return str;
6780af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    }
6880af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips
6980af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    str->append("W: ");
7080af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    str->appendS32(image->width());
7180af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    str->append(" H: ");
7280af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    str->appendS32(image->height());
7380af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips
7480af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    if (image->isOpaque()) {
7580af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips        str->append(" opaque");
7680af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    } else {
7780af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips        str->append(" not-opaque");
7880af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    }
7980af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips
8080af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    str->append(" uniqueID: ");
8180af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    str->appendS32(image->uniqueID());
8280af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips
8380af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips    return str;
8480af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips}
8580af64519b9ba9bbbf07feb8d72968460bfa1422robertphillips
8697cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::BoolToString(bool doAA) {
8797cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mBool = new SkString("Bool doAA: ");
88902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    if (doAA) {
8997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mBool->append("True");
90902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    } else {
9197cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mBool->append("False");
92902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    }
9397cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    return mBool;
94902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
95902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
9697cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::CustomTextToString(const char* text) {
9797cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mText = new SkString(text);
9897cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    return mText;
9997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com}
10097cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com
10197cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::IntToString(int x, const char* text) {
10297cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mInt = new SkString(text);
10397cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mInt->append(" ");
10497cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mInt->appendScalar(SkIntToScalar(x));
10597cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    return mInt;
106902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
107902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
10897cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::IRectToString(const SkIRect& rect) {
10997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mRect = new SkString("SkIRect: ");
11097cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append("L: ");
111195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mRect->appendS32(rect.left());
11297cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append(", T: ");
113195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mRect->appendS32(rect.top());
11497cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append(", R: ");
115195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mRect->appendS32(rect.right());
11697cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append(", B: ");
117195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    mRect->appendS32(rect.bottom());
11897cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    return mRect;
11997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com}
120902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
12197cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::MatrixToString(const SkMatrix& matrix) {
122791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com    SkString* str = new SkString("SkMatrix: ");
1230f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING
124791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com    matrix.toString(str);
12537a2b39ad19d779b2d4c04d49aac55894082018drobertphillips@google.com#endif
126791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com    return str;
12797cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com}
128902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
12997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::PaintToString(const SkPaint& paint) {
130791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com    SkString* str = new SkString;
1310f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING
132791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com    paint.toString(str);
13337a2b39ad19d779b2d4c04d49aac55894082018drobertphillips@google.com#endif
134791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com    return str;
13597cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com}
13697cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com
13797cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::PathToString(const SkPath& path) {
138fe8d5f65ac15d9fa1a23d806820f473330e85670robertphillips    SkString* mPath = new SkString;
1399d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
140fe8d5f65ac15d9fa1a23d806820f473330e85670robertphillips    mPath->appendf("Path (%d) (", path.getGenerationID());
141872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
14251185fe3d4403946d6cc5d5162e1f8e979b19f31robertphillips@google.com    static const char* gFillStrings[] = {
14351185fe3d4403946d6cc5d5162e1f8e979b19f31robertphillips@google.com        "Winding", "EvenOdd", "InverseWinding", "InverseEvenOdd"
14451185fe3d4403946d6cc5d5162e1f8e979b19f31robertphillips@google.com    };
14551185fe3d4403946d6cc5d5162e1f8e979b19f31robertphillips@google.com
14651185fe3d4403946d6cc5d5162e1f8e979b19f31robertphillips@google.com    mPath->append(gFillStrings[path.getFillType()]);
14751185fe3d4403946d6cc5d5162e1f8e979b19f31robertphillips@google.com    mPath->append(", ");
14851185fe3d4403946d6cc5d5162e1f8e979b19f31robertphillips@google.com
149872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    static const char* gConvexityStrings[] = {
1506a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.com        "Unknown", "Convex", "Concave"
151872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    };
152872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    SkASSERT(SkPath::kConcave_Convexity == 2);
153872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
154872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    mPath->append(gConvexityStrings[path.getConvexity()]);
155872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    mPath->append(", ");
156872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
15796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (path.isRect(nullptr)) {
158195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com        mPath->append("isRect, ");
159195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    } else {
160195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com        mPath->append("isNotRect, ");
161195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com    }
162195952f0aee6e2dedf29d095e8be2edc2496dc18robertphillips@google.com
1633d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips    if (path.isOval(nullptr)) {
1643d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips        mPath->append("isOval, ");
1653d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips    } else {
1663d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips        mPath->append("isNotOval, ");
1673d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips    }
1683d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips
1693d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips    SkRRect rrect;
1703d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips    if (path.isRRect(&rrect)) {
1713d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips        mPath->append("isRRect, ");
1723d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips    } else {
1733d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips        mPath->append("isNotRRect, ");
1743d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips    }
1753d2e65439ef98c4b8055e47b04e00d0c8926bf0arobertphillips
176872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    mPath->appendS32(path.countVerbs());
177872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    mPath->append("V, ");
178872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    mPath->appendS32(path.countPoints());
179872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    mPath->append("P): ");
180872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
181872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    static const char* gVerbStrings[] = {
1824a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org        "Move", "Line", "Quad", "Conic", "Cubic", "Close", "Done"
183872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    };
1844a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org    static const int gPtsPerVerb[] = { 1, 1, 2, 2, 3, 0, 0 };
1854a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org    static const int gPtOffsetPerVerb[] = { 0, 1, 1, 1, 1, 0, 0 };
1864a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org    SkASSERT(SkPath::kDone_Verb == 6);
187872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
188872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    SkPath::Iter iter(const_cast<SkPath&>(path), false);
189872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    SkPath::Verb verb;
190872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com    SkPoint points[4];
191872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
1926a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.com    for(verb = iter.next(points, false);
1936a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.com        verb != SkPath::kDone_Verb;
194872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com        verb = iter.next(points, false)) {
195872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
196872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com        mPath->append(gVerbStrings[verb]);
197872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com        mPath->append(" ");
198872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
199872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com        for (int i = 0; i < gPtsPerVerb[verb]; ++i) {
200872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com            mPath->append("(");
201872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com            mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fX);
202872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com            mPath->append(", ");
203872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com            mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fY);
2044a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org            mPath->append(")");
205872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com        }
2064a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org
2074a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org        if (SkPath::kConic_Verb == verb) {
2084a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org            mPath->append("(");
2094a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org            mPath->appendScalar(iter.conicWeight());
2104a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org            mPath->append(")");
2114a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org        }
2124a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org
2134a3ca94322510351f7304af2092d6513442ab9d7commit-bot@chromium.org        mPath->append(" ");
21497cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    }
215872017694b29fd08256ac99e3221bcd0b8a3f32brobertphillips@google.com
21630d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com    SkString* boundStr = SkObjectParser::RectToString(path.getBounds(), "    Bound: ");
21730d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com
21849f085dddff10473b6ebf832a974288300224e60bsalomon    if (boundStr) {
21930d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com        mPath->append(*boundStr);
220385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        delete boundStr;
22130d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com    }
22230d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com
223902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    return mPath;
224902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
225902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
22697cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::PointsToString(const SkPoint pts[], size_t count) {
22797cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mPoints = new SkString("SkPoints pts[]: ");
228902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    for (unsigned int i = 0; i < count; i++) {
22997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mPoints->append("(");
23097cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mPoints->appendScalar(pts[i].fX);
23197cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mPoints->append(",");
23297cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mPoints->appendScalar(pts[i].fY);
23397cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mPoints->append(")");
234902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    }
23597cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    return mPoints;
236902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
237902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
23897cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::PointModeToString(SkCanvas::PointMode mode) {
23997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mMode = new SkString("SkCanvas::PointMode: ");
24092b11f610376dea7192ade22dde31c8bb8ede76cchudy@google.com    if (mode == SkCanvas::kPoints_PointMode) {
24197cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mMode->append("kPoints_PointMode");
24292b11f610376dea7192ade22dde31c8bb8ede76cchudy@google.com    } else if (mode == SkCanvas::kLines_PointMode) {
24397cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mMode->append("kLines_Mode");
24492b11f610376dea7192ade22dde31c8bb8ede76cchudy@google.com    } else if (mode == SkCanvas::kPolygon_PointMode) {
24597cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mMode->append("kPolygon_PointMode");
24692b11f610376dea7192ade22dde31c8bb8ede76cchudy@google.com    }
24792b11f610376dea7192ade22dde31c8bb8ede76cchudy@google.com    return mMode;
24892b11f610376dea7192ade22dde31c8bb8ede76cchudy@google.com}
24992b11f610376dea7192ade22dde31c8bb8ede76cchudy@google.com
25030d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.comSkString* SkObjectParser::RectToString(const SkRect& rect, const char* title) {
25130d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com
25230d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com    SkString* mRect = new SkString;
25372b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
25496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == title) {
25530d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com        mRect->append("SkRect: ");
25630d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com    } else {
25730d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com        mRect->append(title);
25830d35f23ae390043462e2aa5fc6863a4621aa74drobertphillips@google.com    }
25997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append("(");
26097cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->appendScalar(rect.left());
26197cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append(", ");
26297cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->appendScalar(rect.top());
26397cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append(", ");
26497cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->appendScalar(rect.right());
26597cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append(", ");
26697cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->appendScalar(rect.bottom());
26797cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mRect->append(")");
268902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    return mRect;
269902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
270902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
27167baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.comSkString* SkObjectParser::RRectToString(const SkRRect& rrect, const char* title) {
27267baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com
27367baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    SkString* mRRect = new SkString;
27467baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com
27596fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == title) {
27667baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        mRRect->append("SkRRect (");
27767baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        if (rrect.isEmpty()) {
27867baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com            mRRect->append("empty");
27967baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        } else if (rrect.isRect()) {
28067baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com            mRRect->append("rect");
28167baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        } else if (rrect.isOval()) {
28267baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com            mRRect->append("oval");
28367baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        } else if (rrect.isSimple()) {
28467baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com            mRRect->append("simple");
285f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org        } else if (rrect.isNinePatch()) {
286f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org            mRRect->append("nine-patch");
28767baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        } else {
28867baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com            SkASSERT(rrect.isComplex());
28967baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com            mRRect->append("complex");
29067baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        }
29167baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        mRRect->append("): ");
29267baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    } else {
29367baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        mRRect->append(title);
29467baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    }
29567baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->append("(");
29667baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->appendScalar(rrect.rect().left());
29767baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->append(", ");
29867baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->appendScalar(rrect.rect().top());
29967baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->append(", ");
30067baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->appendScalar(rrect.rect().right());
30167baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->append(", ");
30267baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->appendScalar(rrect.rect().bottom());
30367baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->append(") radii: (");
30467baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    for (int i = 0; i < 4; ++i) {
30567baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        const SkVector& radii = rrect.radii((SkRRect::Corner) i);
30667baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        mRRect->appendScalar(radii.fX);
30767baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        mRRect->append(", ");
30867baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        mRRect->appendScalar(radii.fY);
30967baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        if (i < 3) {
31067baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com            mRRect->append(", ");
31167baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com        }
31267baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    }
31367baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    mRRect->append(")");
31467baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com    return mRRect;
31567baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com}
31667baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com
317c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike ReedSkString* SkObjectParser::ClipOpToString(SkClipOp op) {
31897cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mOp = new SkString("SkRegion::Op: ");
319c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed    if (op == kDifference_SkClipOp) {
32097cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mOp->append("kDifference_Op");
321c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed    } else if (op == kIntersect_SkClipOp) {
32297cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mOp->append("kIntersect_Op");
323c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed    } else if (op == kUnion_SkClipOp) {
32497cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mOp->append("kUnion_Op");
325c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed    } else if (op == kXOR_SkClipOp) {
32697cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mOp->append("kXOR_Op");
327c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed    } else if (op == kReverseDifference_SkClipOp) {
32897cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mOp->append("kReverseDifference_Op");
329c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed    } else if (op == kReplace_SkClipOp) {
33097cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mOp->append("kReplace_Op");
331902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    } else {
33297cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com        mOp->append("Unknown Type");
333902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    }
334902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    return mOp;
335902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
336902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
33797cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::RegionToString(const SkRegion& region) {
33897cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mRegion = new SkString("SkRegion: Data unavailable.");
33997cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    return mRegion;
340902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
341902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
3424960eeec4a1f2a772654883d7f3615d47bcd5dc3reedSkString* SkObjectParser::SaveLayerFlagsToString(SkCanvas::SaveLayerFlags saveLayerFlags) {
34397cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mFlags = new SkString("SkCanvas::SaveFlags: ");
3444960eeec4a1f2a772654883d7f3615d47bcd5dc3reed    if (saveLayerFlags & SkCanvas::kIsOpaque_SaveLayerFlag) {
3454960eeec4a1f2a772654883d7f3615d47bcd5dc3reed        mFlags->append("kIsOpaque_SaveLayerFlag ");
346d3ae1d62312791b4355d47f41562de7b11e95636fmalita@google.com    }
3474960eeec4a1f2a772654883d7f3615d47bcd5dc3reed    if (saveLayerFlags & SkCanvas::kPreserveLCDText_SaveLayerFlag) {
3484960eeec4a1f2a772654883d7f3615d47bcd5dc3reed        mFlags->append("kPreserveLCDText_SaveLayerFlag ");
349902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    }
350902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    return mFlags;
351902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
352902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
35397cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.comSkString* SkObjectParser::ScalarToString(SkScalar x, const char* text) {
35497cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    SkString* mScalar = new SkString(text);
35597cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mScalar->append(" ");
35697cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com    mScalar->appendScalar(x);
357902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com    return mScalar;
358902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
359902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
360428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.comSkString* SkObjectParser::TextToString(const void* text, size_t byteLength,
361428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com                                       SkPaint::TextEncoding encoding) {
362428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com
363428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com    SkString* decodedText = new SkString();
364428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com    switch (encoding) {
365428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        case SkPaint::kUTF8_TextEncoding: {
366428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            decodedText->append("UTF-8: ");
367428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            decodedText->append((const char*)text, byteLength);
368428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            break;
369428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        }
370428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        case SkPaint::kUTF16_TextEncoding: {
371428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            decodedText->append("UTF-16: ");
372f61ebc0927d773fe4152a3521cdc3de0112f636eskia.committer@gmail.com            size_t sizeNeeded = SkUTF16_ToUTF8((uint16_t*)text,
373f61ebc0927d773fe4152a3521cdc3de0112f636eskia.committer@gmail.com                                                SkToS32(byteLength / 2),
37496fcdcc219d2a0d3579719b84b28bede76efba64halcanary                                                nullptr);
375b9050d73f98912cdac6a4e058523e6a92e497f69scroggo@google.com            SkAutoSTMalloc<0x100, char> utf8(sizeNeeded);
376a4662865e37a2ca95b5e3379072f6a274acc8ac8robertphillips@google.com            SkUTF16_ToUTF8((uint16_t*)text, SkToS32(byteLength / 2), utf8);
377428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            decodedText->append(utf8, sizeNeeded);
378428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            break;
379428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        }
380428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        case SkPaint::kUTF32_TextEncoding: {
381428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            decodedText->append("UTF-32: ");
382428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            const SkUnichar* begin = (const SkUnichar*)text;
383428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            const SkUnichar* end = (const SkUnichar*)((const char*)text + byteLength);
384428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            for (const SkUnichar* unichar = begin; unichar < end; ++unichar) {
385428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com                decodedText->appendUnichar(*unichar);
386428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            }
387428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            break;
388428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        }
389428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        case SkPaint::kGlyphID_TextEncoding: {
390428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            decodedText->append("GlyphID: ");
391428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            const uint16_t* begin = (const uint16_t*)text;
392428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            const uint16_t* end = (const uint16_t*)((const char*)text + byteLength);
393428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            for (const uint16_t* glyph = begin; glyph < end; ++glyph) {
394428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com                decodedText->append("0x");
395428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com                decodedText->appendHex(*glyph);
396428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com                decodedText->append(" ");
397428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            }
398428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            break;
399428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        }
400428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com        default:
401428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            decodedText->append("Unknown text encoding.");
402428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com            break;
403428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com    }
404428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com
405428fc4a37b66ac927d5b8c3a2938e578ea70cbb8bungeman@google.com    return decodedText;
406902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
407ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev
408ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan IlievSkString* SkObjectParser::LatticeToString(const SkCanvas::Lattice& lattice) {
409ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    SkString* mLattice = new SkString;
410ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    mLattice->append("Lattice: ");
411ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    mLattice->append("(X: ");
412ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    mLattice->appendS32(lattice.fXCount);
413ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    mLattice->append(", Y:");
414ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    mLattice->appendS32(lattice.fYCount);
415ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    mLattice->append(", Bounds:");
416ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    if (nullptr != lattice.fBounds) {
417ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev        mLattice->append(*IRectToString(*lattice.fBounds));
418ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    } else {
419ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev        mLattice->append("null");
420ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    }
421ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    mLattice->append(")");
422ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev    return mLattice;
423ac42aebb7b49ef3d916da1e5a75b4c7cd4cfb119Stan Iliev}
424