2014-04-11 18:33:31 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2014 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2014-04-01 16:24:06 +00:00
|
|
|
#ifndef SkRecords_DEFINED
|
|
|
|
#define SkRecords_DEFINED
|
|
|
|
|
2016-03-05 00:36:20 +00:00
|
|
|
#include "SkData.h"
|
2014-04-01 16:24:06 +00:00
|
|
|
#include "SkCanvas.h"
|
2015-02-06 16:36:15 +00:00
|
|
|
#include "SkDrawable.h"
|
2016-01-07 19:28:08 +00:00
|
|
|
#include "SkImageFilter.h"
|
2015-07-07 17:22:31 +00:00
|
|
|
#include "SkMatrix.h"
|
2015-08-05 20:57:49 +00:00
|
|
|
#include "SkPath.h"
|
2014-08-07 19:19:50 +00:00
|
|
|
#include "SkPicture.h"
|
2015-08-05 20:57:49 +00:00
|
|
|
#include "SkRect.h"
|
|
|
|
#include "SkRRect.h"
|
2015-06-24 17:29:17 +00:00
|
|
|
#include "SkRSXform.h"
|
2016-03-05 00:36:20 +00:00
|
|
|
#include "SkString.h"
|
2014-08-21 15:53:26 +00:00
|
|
|
#include "SkTextBlob.h"
|
2014-08-07 19:19:50 +00:00
|
|
|
|
2016-06-08 00:21:10 +00:00
|
|
|
// Windows.h, will pull in all of the GDI defines. GDI #defines
|
|
|
|
// DrawText to DrawTextA or DrawTextW, but SkRecord has a struct
|
|
|
|
// called DrawText. Since this file does not use GDI, undefing
|
|
|
|
// DrawText makes things less confusing.
|
|
|
|
#ifdef DrawText
|
|
|
|
#undef DrawText
|
|
|
|
#endif
|
|
|
|
|
2014-08-21 15:53:26 +00:00
|
|
|
namespace SkRecords {
|
|
|
|
|
2014-04-01 16:24:06 +00:00
|
|
|
// A list of all the types of canvas calls we can record.
|
|
|
|
// Each of these is reified into a struct below.
|
|
|
|
//
|
|
|
|
// (We're using the macro-of-macro trick here to do several different things with the same list.)
|
|
|
|
//
|
|
|
|
// We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords
|
|
|
|
// types polymorphically. (See SkRecord::Record::{visit,mutate} for an example.)
|
2014-05-07 22:59:38 +00:00
|
|
|
//
|
|
|
|
// Order doesn't technically matter here, but the compiler can generally generate better code if
|
|
|
|
// you keep them semantically grouped, especially the Draws. It's also nice to leave NoOp at 0.
|
2014-04-22 16:57:20 +00:00
|
|
|
#define SK_RECORD_TYPES(M) \
|
|
|
|
M(NoOp) \
|
|
|
|
M(Restore) \
|
|
|
|
M(Save) \
|
|
|
|
M(SaveLayer) \
|
|
|
|
M(SetMatrix) \
|
2016-07-13 21:05:28 +00:00
|
|
|
M(TranslateZ) \
|
2015-11-19 20:08:24 +00:00
|
|
|
M(Concat) \
|
2014-04-22 16:57:20 +00:00
|
|
|
M(ClipPath) \
|
|
|
|
M(ClipRRect) \
|
|
|
|
M(ClipRect) \
|
|
|
|
M(ClipRegion) \
|
2014-11-18 19:08:05 +00:00
|
|
|
M(DrawDrawable) \
|
2014-10-16 18:58:39 +00:00
|
|
|
M(DrawImage) \
|
2016-08-02 15:05:56 +00:00
|
|
|
M(DrawImageLattice) \
|
2014-10-16 18:58:39 +00:00
|
|
|
M(DrawImageRect) \
|
2015-06-25 19:32:03 +00:00
|
|
|
M(DrawImageNine) \
|
2014-04-22 16:57:20 +00:00
|
|
|
M(DrawDRRect) \
|
|
|
|
M(DrawOval) \
|
|
|
|
M(DrawPaint) \
|
|
|
|
M(DrawPath) \
|
2014-08-07 14:49:53 +00:00
|
|
|
M(DrawPatch) \
|
2014-08-07 19:19:50 +00:00
|
|
|
M(DrawPicture) \
|
2016-07-21 17:25:54 +00:00
|
|
|
M(DrawShadowedPicture) \
|
2014-04-22 16:57:20 +00:00
|
|
|
M(DrawPoints) \
|
|
|
|
M(DrawPosText) \
|
|
|
|
M(DrawPosTextH) \
|
2014-08-20 15:09:46 +00:00
|
|
|
M(DrawText) \
|
|
|
|
M(DrawTextOnPath) \
|
2016-07-07 19:47:17 +00:00
|
|
|
M(DrawTextRSXform) \
|
2014-04-22 16:57:20 +00:00
|
|
|
M(DrawRRect) \
|
|
|
|
M(DrawRect) \
|
2014-09-04 21:12:44 +00:00
|
|
|
M(DrawTextBlob) \
|
2015-06-24 17:29:17 +00:00
|
|
|
M(DrawAtlas) \
|
2016-03-05 00:36:20 +00:00
|
|
|
M(DrawVertices) \
|
|
|
|
M(DrawAnnotation)
|
2014-04-01 16:24:06 +00:00
|
|
|
|
|
|
|
// Defines SkRecords::Type, an enum of all record types.
|
|
|
|
#define ENUM(T) T##_Type,
|
|
|
|
enum Type { SK_RECORD_TYPES(ENUM) };
|
|
|
|
#undef ENUM
|
|
|
|
|
2014-09-18 18:16:31 +00:00
|
|
|
#define ACT_AS_PTR(ptr) \
|
|
|
|
operator T*() const { return ptr; } \
|
|
|
|
T* operator->() const { return ptr; }
|
2014-04-22 16:57:20 +00:00
|
|
|
|
2014-04-15 14:27:14 +00:00
|
|
|
// An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
|
|
|
|
template <typename T>
|
|
|
|
class Optional : SkNoncopyable {
|
|
|
|
public:
|
2015-05-19 18:11:26 +00:00
|
|
|
Optional() : fPtr(nullptr) {}
|
2014-04-15 14:27:14 +00:00
|
|
|
Optional(T* ptr) : fPtr(ptr) {}
|
2015-09-28 17:33:02 +00:00
|
|
|
Optional(Optional&& o) : fPtr(o.fPtr) {
|
|
|
|
o.fPtr = nullptr;
|
|
|
|
}
|
2014-04-15 14:27:14 +00:00
|
|
|
~Optional() { if (fPtr) fPtr->~T(); }
|
|
|
|
|
2014-04-22 16:57:20 +00:00
|
|
|
ACT_AS_PTR(fPtr);
|
|
|
|
private:
|
|
|
|
T* fPtr;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Like Optional, but ptr must not be NULL.
|
|
|
|
template <typename T>
|
|
|
|
class Adopted : SkNoncopyable {
|
|
|
|
public:
|
|
|
|
Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); }
|
2014-04-24 15:33:48 +00:00
|
|
|
Adopted(Adopted* source) {
|
|
|
|
// Transfer ownership from source to this.
|
|
|
|
fPtr = source->fPtr;
|
|
|
|
source->fPtr = NULL;
|
|
|
|
}
|
|
|
|
~Adopted() { if (fPtr) fPtr->~T(); }
|
2014-04-22 16:57:20 +00:00
|
|
|
|
|
|
|
ACT_AS_PTR(fPtr);
|
2014-04-15 14:27:14 +00:00
|
|
|
private:
|
|
|
|
T* fPtr;
|
|
|
|
};
|
|
|
|
|
|
|
|
// PODArray doesn't own the pointer's memory, and we assume the data is POD.
|
|
|
|
template <typename T>
|
2014-04-24 15:33:48 +00:00
|
|
|
class PODArray {
|
2014-04-15 14:27:14 +00:00
|
|
|
public:
|
2015-05-19 18:11:26 +00:00
|
|
|
PODArray() {}
|
2014-04-15 14:27:14 +00:00
|
|
|
PODArray(T* ptr) : fPtr(ptr) {}
|
2014-04-24 15:33:48 +00:00
|
|
|
// Default copy and assign.
|
2014-04-15 14:27:14 +00:00
|
|
|
|
2014-04-22 16:57:20 +00:00
|
|
|
ACT_AS_PTR(fPtr);
|
2014-04-15 14:27:14 +00:00
|
|
|
private:
|
|
|
|
T* fPtr;
|
|
|
|
};
|
|
|
|
|
2014-04-22 18:32:58 +00:00
|
|
|
#undef ACT_AS_PTR
|
|
|
|
|
2014-12-01 19:03:37 +00:00
|
|
|
// SkPath::getBounds() isn't thread safe unless we precache the bounds in a singlethreaded context.
|
2015-01-20 21:47:19 +00:00
|
|
|
// SkPath::cheapComputeDirection() is similar.
|
|
|
|
// Recording is a convenient time to cache these, or we can delay it to between record and playback.
|
|
|
|
struct PreCachedPath : public SkPath {
|
2015-05-19 18:11:26 +00:00
|
|
|
PreCachedPath() {}
|
2015-09-28 17:33:02 +00:00
|
|
|
PreCachedPath(const SkPath& path);
|
2014-12-01 19:03:37 +00:00
|
|
|
};
|
2014-04-01 16:24:06 +00:00
|
|
|
|
2014-12-01 19:03:37 +00:00
|
|
|
// Like SkPath::getBounds(), SkMatrix::getType() isn't thread safe unless we precache it.
|
|
|
|
// This may not cover all SkMatrices used by the picture (e.g. some could be hiding in a shader).
|
|
|
|
struct TypedMatrix : public SkMatrix {
|
2015-05-19 18:11:26 +00:00
|
|
|
TypedMatrix() {}
|
2015-09-28 17:33:02 +00:00
|
|
|
TypedMatrix(const SkMatrix& matrix);
|
2014-04-01 16:24:06 +00:00
|
|
|
};
|
|
|
|
|
2015-09-28 17:33:02 +00:00
|
|
|
enum Tags {
|
|
|
|
kDraw_Tag = 1, // May draw something (usually named DrawFoo).
|
|
|
|
kHasImage_Tag = 2, // Contains an SkImage or SkBitmap.
|
|
|
|
kHasText_Tag = 4, // Contains text.
|
2016-08-01 20:17:47 +00:00
|
|
|
kHasPaint_Tag = 8, // May have an SkPaint field, at least optionally.
|
2015-09-28 17:33:02 +00:00
|
|
|
};
|
2014-04-01 16:24:06 +00:00
|
|
|
|
2015-09-28 17:33:02 +00:00
|
|
|
// A macro to make it a little easier to define a struct that can be stored in SkRecord.
|
|
|
|
#define RECORD(T, tags, ...) \
|
|
|
|
struct T { \
|
|
|
|
static const Type kType = T##_Type; \
|
|
|
|
static const int kTags = tags; \
|
|
|
|
__VA_ARGS__; \
|
|
|
|
};
|
|
|
|
|
|
|
|
RECORD(NoOp, 0);
|
|
|
|
RECORD(Restore, 0,
|
|
|
|
SkIRect devBounds;
|
|
|
|
TypedMatrix matrix);
|
|
|
|
RECORD(Save, 0);
|
2014-04-01 16:24:06 +00:00
|
|
|
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(SaveLayer, kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
Optional<SkRect> bounds;
|
|
|
|
Optional<SkPaint> paint;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<const SkImageFilter> backdrop;
|
2015-12-18 15:09:18 +00:00
|
|
|
SkCanvas::SaveLayerFlags saveLayerFlags);
|
2015-09-28 17:33:02 +00:00
|
|
|
|
|
|
|
RECORD(SetMatrix, 0,
|
|
|
|
TypedMatrix matrix);
|
2015-11-19 20:08:24 +00:00
|
|
|
RECORD(Concat, 0,
|
|
|
|
TypedMatrix matrix);
|
2014-04-01 16:24:06 +00:00
|
|
|
|
2016-07-13 21:05:28 +00:00
|
|
|
RECORD(TranslateZ, 0, SkScalar z);
|
|
|
|
|
2014-11-20 17:14:28 +00:00
|
|
|
struct RegionOpAndAA {
|
2015-05-19 18:11:26 +00:00
|
|
|
RegionOpAndAA() {}
|
2014-11-20 17:14:28 +00:00
|
|
|
RegionOpAndAA(SkRegion::Op op, bool aa) : op(op), aa(aa) {}
|
|
|
|
SkRegion::Op op : 31; // This really only needs to be 3, but there's no win today to do so.
|
|
|
|
unsigned aa : 1; // MSVC won't pack an enum with an bool, so we call this an unsigned.
|
|
|
|
};
|
2015-08-20 14:57:51 +00:00
|
|
|
static_assert(sizeof(RegionOpAndAA) == 4, "RegionOpAndAASize");
|
2014-11-20 17:14:28 +00:00
|
|
|
|
2015-09-28 17:33:02 +00:00
|
|
|
RECORD(ClipPath, 0,
|
|
|
|
SkIRect devBounds;
|
|
|
|
PreCachedPath path;
|
|
|
|
RegionOpAndAA opAA);
|
|
|
|
RECORD(ClipRRect, 0,
|
|
|
|
SkIRect devBounds;
|
|
|
|
SkRRect rrect;
|
|
|
|
RegionOpAndAA opAA);
|
|
|
|
RECORD(ClipRect, 0,
|
|
|
|
SkIRect devBounds;
|
|
|
|
SkRect rect;
|
|
|
|
RegionOpAndAA opAA);
|
|
|
|
RECORD(ClipRegion, 0,
|
|
|
|
SkIRect devBounds;
|
|
|
|
SkRegion region;
|
|
|
|
SkRegion::Op op);
|
2014-04-01 16:24:06 +00:00
|
|
|
|
2014-05-07 22:59:38 +00:00
|
|
|
// While not strictly required, if you have an SkPaint, it's fastest to put it first.
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
SkRRect outer;
|
|
|
|
SkRRect inner);
|
|
|
|
RECORD(DrawDrawable, kDraw_Tag,
|
|
|
|
Optional<SkMatrix> matrix;
|
|
|
|
SkRect worstCaseBounds;
|
|
|
|
int32_t index);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
Optional<SkPaint> paint;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<const SkImage> image;
|
2015-09-28 17:33:02 +00:00
|
|
|
SkScalar left;
|
|
|
|
SkScalar top);
|
2016-08-02 15:05:56 +00:00
|
|
|
RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
|
|
|
Optional<SkPaint> paint;
|
|
|
|
sk_sp<const SkImage> image;
|
|
|
|
int xCount;
|
|
|
|
PODArray<int> xDivs;
|
|
|
|
int yCount;
|
|
|
|
PODArray<int> yDivs;
|
|
|
|
SkRect dst);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
Optional<SkPaint> paint;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<const SkImage> image;
|
2015-09-28 17:33:02 +00:00
|
|
|
Optional<SkRect> src;
|
|
|
|
SkRect dst;
|
|
|
|
SkCanvas::SrcRectConstraint constraint);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
Optional<SkPaint> paint;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<const SkImage> image;
|
2015-09-28 17:33:02 +00:00
|
|
|
SkIRect center;
|
|
|
|
SkRect dst);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
SkRect oval);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
PreCachedPath path);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
Optional<SkPaint> paint;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<const SkPicture> picture;
|
2015-09-28 17:33:02 +00:00
|
|
|
TypedMatrix matrix);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawShadowedPicture, kDraw_Tag|kHasPaint_Tag,
|
2016-07-21 17:25:54 +00:00
|
|
|
Optional<SkPaint> paint;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<const SkPicture> picture;
|
2016-07-21 17:25:54 +00:00
|
|
|
TypedMatrix matrix);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
SkCanvas::PointMode mode;
|
|
|
|
unsigned count;
|
|
|
|
SkPoint* pts);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawPosText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
PODArray<char> text;
|
|
|
|
size_t byteLength;
|
|
|
|
PODArray<SkPoint> pos);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawPosTextH, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
PODArray<char> text;
|
|
|
|
unsigned byteLength;
|
|
|
|
SkScalar y;
|
|
|
|
PODArray<SkScalar> xpos);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
SkRRect rrect);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
SkRect rect);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
PODArray<char> text;
|
|
|
|
size_t byteLength;
|
|
|
|
SkScalar x;
|
|
|
|
SkScalar y);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<const SkTextBlob> blob;
|
2015-09-28 17:33:02 +00:00
|
|
|
SkScalar x;
|
|
|
|
SkScalar y);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawTextOnPath, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
PODArray<char> text;
|
|
|
|
size_t byteLength;
|
|
|
|
PreCachedPath path;
|
|
|
|
TypedMatrix matrix);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawTextRSXform, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
|
2016-07-07 19:47:17 +00:00
|
|
|
SkPaint paint;
|
|
|
|
PODArray<char> text;
|
|
|
|
size_t byteLength;
|
|
|
|
PODArray<SkRSXform> xforms;
|
|
|
|
Optional<SkRect> cull);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
PODArray<SkPoint> cubics;
|
|
|
|
PODArray<SkColor> colors;
|
|
|
|
PODArray<SkPoint> texCoords;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<SkXfermode> xmode);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
Optional<SkPaint> paint;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<const SkImage> atlas;
|
2015-09-28 17:33:02 +00:00
|
|
|
PODArray<SkRSXform> xforms;
|
|
|
|
PODArray<SkRect> texs;
|
|
|
|
PODArray<SkColor> colors;
|
|
|
|
int count;
|
|
|
|
SkXfermode::Mode mode;
|
|
|
|
Optional<SkRect> cull);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
|
2015-09-28 17:33:02 +00:00
|
|
|
SkPaint paint;
|
|
|
|
SkCanvas::VertexMode vmode;
|
|
|
|
int vertexCount;
|
|
|
|
PODArray<SkPoint> vertices;
|
|
|
|
PODArray<SkPoint> texs;
|
|
|
|
PODArray<SkColor> colors;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<SkXfermode> xmode;
|
2015-09-28 17:33:02 +00:00
|
|
|
PODArray<uint16_t> indices;
|
|
|
|
int indexCount);
|
2016-08-01 20:17:47 +00:00
|
|
|
RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548
|
2016-03-05 00:36:20 +00:00
|
|
|
SkRect rect;
|
|
|
|
SkString key;
|
2016-08-01 18:24:03 +00:00
|
|
|
sk_sp<SkData> value);
|
2015-09-28 17:33:02 +00:00
|
|
|
#undef RECORD
|
2014-04-01 16:24:06 +00:00
|
|
|
|
|
|
|
} // namespace SkRecords
|
|
|
|
|
|
|
|
#endif//SkRecords_DEFINED
|