Home | History | Annotate | Download | only in debugger
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #ifndef SKDRAWCOMMAND_H_
     10 #define SKDRAWCOMMAND_H_
     11 
     12 #include "SkPictureFlat.h"
     13 #include "SkCanvas.h"
     14 #include "SkString.h"
     15 
     16 class SK_API SkDrawCommand {
     17 public:
     18     /* TODO(chudy): Remove subclasses. */
     19     SkDrawCommand(DrawType drawType);
     20     SkDrawCommand();
     21 
     22     virtual ~SkDrawCommand();
     23 
     24     virtual SkString toString();
     25 
     26     void setOffset(size_t offset) { fOffset = offset; }
     27     virtual size_t offset() { return fOffset; }
     28 
     29     virtual const char* toCString() {
     30         return GetCommandString(fDrawType);
     31     }
     32 
     33     bool isVisible() const {
     34         return fVisible;
     35     }
     36 
     37     void setVisible(bool toggle) {
     38         fVisible = toggle;
     39     }
     40 
     41     SkTDArray<SkString*>* Info() {return &fInfo; };
     42     virtual void execute(SkCanvas* canvas) = 0;
     43     virtual void vizExecute(SkCanvas* canvas) { };
     44     /** Does nothing by default, but used by save() and restore()-type
     45         subclasses to track unresolved save() calls. */
     46     virtual void trackSaveState(int* state) { };
     47 
     48     // The next "active" system is only used by save, saveLayer, restore,
     49     // pushCull and popCull. It is used in two ways:
     50     // To determine which saveLayers are currently active (at a
     51     // given point in the rendering).
     52     //      saves just return a kPushLayer action but don't track active state
     53     //      restores just return a kPopLayer action
     54     //      saveLayers return kPushLayer but also track the active state
     55     // To determine which culls are currently active (at a given point)
     56     // in the rendering).
     57     //      pushCulls return a kPushCull action
     58     //      popCulls  return a kPopCull action
     59     enum Action {
     60         kNone_Action,
     61         kPopLayer_Action,
     62         kPushLayer_Action,
     63         kPopCull_Action,
     64         kPushCull_Action
     65     };
     66     virtual Action action() const { return kNone_Action; }
     67     virtual void setActive(bool active) {}
     68     virtual bool active() const { return false; }
     69 
     70     DrawType getType() { return fDrawType; };
     71 
     72     virtual bool render(SkCanvas* canvas) const { return false; }
     73 
     74     static const char* GetCommandString(DrawType type);
     75 
     76 protected:
     77     SkTDArray<SkString*> fInfo;
     78 
     79 private:
     80     DrawType fDrawType;
     81     size_t fOffset;
     82     bool   fVisible;
     83 };
     84 
     85 class SkRestoreCommand : public SkDrawCommand {
     86 public:
     87     SkRestoreCommand();
     88     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     89     virtual void trackSaveState(int* state) SK_OVERRIDE;
     90     virtual Action action() const SK_OVERRIDE { return kPopLayer_Action; }
     91 
     92 private:
     93     typedef SkDrawCommand INHERITED;
     94 };
     95 
     96 class SkClearCommand : public SkDrawCommand {
     97 public:
     98     SkClearCommand(SkColor color);
     99     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    100 private:
    101     SkColor fColor;
    102 
    103     typedef SkDrawCommand INHERITED;
    104 };
    105 
    106 class SkClipPathCommand : public SkDrawCommand {
    107 public:
    108     SkClipPathCommand(const SkPath& path, SkRegion::Op op, bool doAA);
    109     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    110     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    111 private:
    112     SkPath       fPath;
    113     SkRegion::Op fOp;
    114     bool         fDoAA;
    115 
    116     typedef SkDrawCommand INHERITED;
    117 };
    118 
    119 class SkClipRegionCommand : public SkDrawCommand {
    120 public:
    121     SkClipRegionCommand(const SkRegion& region, SkRegion::Op op);
    122     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    123 private:
    124     SkRegion     fRegion;
    125     SkRegion::Op fOp;
    126 
    127     typedef SkDrawCommand INHERITED;
    128 };
    129 
    130 class SkClipRectCommand : public SkDrawCommand {
    131 public:
    132     SkClipRectCommand(const SkRect& rect, SkRegion::Op op, bool doAA);
    133     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    134 
    135     const SkRect& rect() const { return fRect; }
    136     SkRegion::Op op() const { return fOp; }
    137     bool doAA() const { return fDoAA; }
    138 
    139 private:
    140     SkRect       fRect;
    141     SkRegion::Op fOp;
    142     bool         fDoAA;
    143 
    144     typedef SkDrawCommand INHERITED;
    145 };
    146 
    147 class SkClipRRectCommand : public SkDrawCommand {
    148 public:
    149     SkClipRRectCommand(const SkRRect& rrect, SkRegion::Op op, bool doAA);
    150     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    151     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    152 
    153     const SkRRect& rrect() const { return fRRect; }
    154     SkRegion::Op op() const { return fOp; }
    155     bool doAA() const { return fDoAA; }
    156 
    157 private:
    158     SkRRect      fRRect;
    159     SkRegion::Op fOp;
    160     bool         fDoAA;
    161 
    162     typedef SkDrawCommand INHERITED;
    163 };
    164 
    165 class SkConcatCommand : public SkDrawCommand {
    166 public:
    167     SkConcatCommand(const SkMatrix& matrix);
    168     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    169 private:
    170     SkMatrix fMatrix;
    171 
    172     typedef SkDrawCommand INHERITED;
    173 };
    174 
    175 class SkDrawBitmapCommand : public SkDrawCommand {
    176 public:
    177     SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
    178                         const SkPaint* paint);
    179     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    180     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    181 private:
    182     SkBitmap fBitmap;
    183     SkScalar fLeft;
    184     SkScalar fTop;
    185     SkPaint  fPaint;
    186     SkPaint* fPaintPtr;
    187 
    188     typedef SkDrawCommand INHERITED;
    189 };
    190 
    191 class SkDrawBitmapMatrixCommand : public SkDrawCommand {
    192 public:
    193     SkDrawBitmapMatrixCommand(const SkBitmap& bitmap, const SkMatrix& matrix,
    194                               const SkPaint* paint);
    195     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    196     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    197 private:
    198     SkBitmap fBitmap;
    199     SkMatrix fMatrix;
    200     SkPaint  fPaint;
    201     SkPaint* fPaintPtr;
    202 
    203     typedef SkDrawCommand INHERITED;
    204 };
    205 
    206 class SkDrawBitmapNineCommand : public SkDrawCommand {
    207 public:
    208     SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
    209                             const SkRect& dst, const SkPaint* paint);
    210     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    211     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    212 private:
    213     SkBitmap fBitmap;
    214     SkIRect  fCenter;
    215     SkRect   fDst;
    216     SkPaint  fPaint;
    217     SkPaint* fPaintPtr;
    218 
    219     typedef SkDrawCommand INHERITED;
    220 };
    221 
    222 class SkDrawBitmapRectCommand : public SkDrawCommand {
    223 public:
    224     SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
    225                             const SkRect& dst, const SkPaint* paint,
    226                             SkCanvas::DrawBitmapRectFlags flags);
    227     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    228     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    229 
    230     const SkBitmap& bitmap() const { return fBitmap; }
    231 
    232     // The non-const 'paint' method allows modification of this object's
    233     // SkPaint. For this reason the ctor and setPaint method make a local copy.
    234     // The 'fPaintPtr' member acts a signal that the local SkPaint is valid
    235     // (since only an SkPaint* is passed into the ctor).
    236     const SkPaint* paint() const { return fPaintPtr; }
    237     SkPaint* paint() { return fPaintPtr; }
    238 
    239     void setPaint(const SkPaint& paint) { fPaint = paint; fPaintPtr = &fPaint; }
    240 
    241     const SkRect* srcRect() const { return fSrc.isEmpty() ? NULL : &fSrc; }
    242     void setSrcRect(const SkRect& src) { fSrc = src; }
    243 
    244     const SkRect& dstRect() const { return fDst; }
    245     void setDstRect(const SkRect& dst) { fDst = dst; }
    246 
    247     SkCanvas::DrawBitmapRectFlags flags() const { return fFlags; }
    248     void setFlags(SkCanvas::DrawBitmapRectFlags flags) { fFlags = flags; }
    249 
    250 private:
    251     SkBitmap                      fBitmap;
    252     SkRect                        fSrc;
    253     SkRect                        fDst;
    254     SkPaint                       fPaint;
    255     SkPaint*                      fPaintPtr;
    256     SkCanvas::DrawBitmapRectFlags fFlags;
    257 
    258     typedef SkDrawCommand INHERITED;
    259 };
    260 
    261 class SkDrawDataCommand : public SkDrawCommand {
    262 public:
    263     SkDrawDataCommand(const void* data, size_t length);
    264     virtual ~SkDrawDataCommand() { delete [] fData; }
    265     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    266 private:
    267     char*  fData;
    268     size_t fLength;
    269 
    270     typedef SkDrawCommand INHERITED;
    271 };
    272 
    273 class SkBeginCommentGroupCommand : public SkDrawCommand {
    274 public:
    275     SkBeginCommentGroupCommand(const char* description);
    276     virtual void execute(SkCanvas* canvas) SK_OVERRIDE {
    277         canvas->beginCommentGroup(fDescription.c_str());
    278     };
    279 private:
    280     SkString fDescription;
    281 
    282     typedef SkDrawCommand INHERITED;
    283 };
    284 
    285 class SkCommentCommand : public SkDrawCommand {
    286 public:
    287     SkCommentCommand(const char* kywd, const char* value);
    288     virtual void execute(SkCanvas* canvas) SK_OVERRIDE {
    289         canvas->addComment(fKywd.c_str(), fValue.c_str());
    290     };
    291 private:
    292     SkString fKywd;
    293     SkString fValue;
    294 
    295     typedef SkDrawCommand INHERITED;
    296 };
    297 
    298 class SkEndCommentGroupCommand : public SkDrawCommand {
    299 public:
    300     SkEndCommentGroupCommand();
    301     virtual void execute(SkCanvas* canvas) SK_OVERRIDE {
    302         canvas->endCommentGroup();
    303     };
    304 private:
    305     typedef SkDrawCommand INHERITED;
    306 };
    307 
    308 class SkDrawOvalCommand : public SkDrawCommand {
    309 public:
    310     SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint);
    311     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    312     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    313 private:
    314     SkRect  fOval;
    315     SkPaint fPaint;
    316 
    317     typedef SkDrawCommand INHERITED;
    318 };
    319 
    320 class SkDrawPaintCommand : public SkDrawCommand {
    321 public:
    322     SkDrawPaintCommand(const SkPaint& paint);
    323     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    324     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    325 private:
    326     SkPaint fPaint;
    327 
    328     typedef SkDrawCommand INHERITED;
    329 };
    330 
    331 class SkDrawPathCommand : public SkDrawCommand {
    332 public:
    333     SkDrawPathCommand(const SkPath& path, const SkPaint& paint);
    334     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    335     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    336 
    337 private:
    338     SkPath   fPath;
    339     SkPaint  fPaint;
    340 
    341     typedef SkDrawCommand INHERITED;
    342 };
    343 
    344 class SkDrawPictureCommand : public SkDrawCommand {
    345 public:
    346     SkDrawPictureCommand(const SkPicture* picture);
    347     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    348     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    349 
    350 private:
    351     SkAutoTUnref<const SkPicture> fPicture;
    352 
    353     typedef SkDrawCommand INHERITED;
    354 };
    355 
    356 class SkDrawPointsCommand : public SkDrawCommand {
    357 public:
    358     SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
    359                         const SkPaint& paint);
    360     virtual ~SkDrawPointsCommand() { delete [] fPts; }
    361     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    362     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    363 private:
    364     SkCanvas::PointMode fMode;
    365     size_t              fCount;
    366     SkPoint*            fPts;
    367     SkPaint             fPaint;
    368 
    369     typedef SkDrawCommand INHERITED;
    370 };
    371 
    372 class SkDrawTextCommand : public SkDrawCommand {
    373 public:
    374     SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
    375                       const SkPaint& paint);
    376     virtual ~SkDrawTextCommand() { delete [] fText; }
    377     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    378 private:
    379     char*    fText;
    380     size_t   fByteLength;
    381     SkScalar fX;
    382     SkScalar fY;
    383     SkPaint  fPaint;
    384 
    385     typedef SkDrawCommand INHERITED;
    386 };
    387 
    388 class SkDrawPosTextCommand : public SkDrawCommand {
    389 public:
    390     SkDrawPosTextCommand(const void* text, size_t byteLength, const SkPoint pos[],
    391                          const SkPaint& paint);
    392     virtual ~SkDrawPosTextCommand() { delete [] fPos; delete [] fText; }
    393     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    394 private:
    395     char*    fText;
    396     size_t   fByteLength;
    397     SkPoint* fPos;
    398     SkPaint  fPaint;
    399 
    400     typedef SkDrawCommand INHERITED;
    401 };
    402 
    403 class SkDrawTextOnPathCommand : public SkDrawCommand {
    404 public:
    405     SkDrawTextOnPathCommand(const void* text, size_t byteLength, const SkPath& path,
    406                             const SkMatrix* matrix, const SkPaint& paint);
    407     virtual ~SkDrawTextOnPathCommand() { delete [] fText; }
    408     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    409 private:
    410     char*    fText;
    411     size_t   fByteLength;
    412     SkPath   fPath;
    413     SkMatrix fMatrix;
    414     SkPaint  fPaint;
    415 
    416     typedef SkDrawCommand INHERITED;
    417 };
    418 
    419 class SkDrawPosTextHCommand : public SkDrawCommand {
    420 public:
    421     SkDrawPosTextHCommand(const void* text, size_t byteLength, const SkScalar xpos[],
    422                           SkScalar constY, const SkPaint& paint);
    423     virtual ~SkDrawPosTextHCommand() { delete [] fXpos; delete [] fText; }
    424     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    425 private:
    426     SkScalar* fXpos;
    427     char*     fText;
    428     size_t    fByteLength;
    429     SkScalar  fConstY;
    430     SkPaint   fPaint;
    431 
    432     typedef SkDrawCommand INHERITED;
    433 };
    434 
    435 class SkDrawRectCommand : public SkDrawCommand {
    436 public:
    437     SkDrawRectCommand(const SkRect& rect, const SkPaint& paint);
    438     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    439 
    440     const SkRect& rect() const   { return fRect; }
    441     const SkPaint& paint() const { return fPaint; }
    442 private:
    443     SkRect  fRect;
    444     SkPaint fPaint;
    445 
    446     typedef SkDrawCommand INHERITED;
    447 };
    448 
    449 class SkDrawRRectCommand : public SkDrawCommand {
    450 public:
    451     SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint);
    452     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    453     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    454 private:
    455     SkRRect fRRect;
    456     SkPaint fPaint;
    457 
    458     typedef SkDrawCommand INHERITED;
    459 };
    460 
    461 class SkDrawDRRectCommand : public SkDrawCommand {
    462 public:
    463     SkDrawDRRectCommand(const SkRRect& outer, const SkRRect& inner,
    464                         const SkPaint& paint);
    465     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    466     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    467 private:
    468     SkRRect fOuter;
    469     SkRRect fInner;
    470     SkPaint fPaint;
    471 
    472     typedef SkDrawCommand INHERITED;
    473 };
    474 
    475 class SkDrawSpriteCommand : public SkDrawCommand {
    476 public:
    477     SkDrawSpriteCommand(const SkBitmap& bitmap, int left, int top, const SkPaint* paint);
    478     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    479     virtual bool render(SkCanvas* canvas) const SK_OVERRIDE;
    480 private:
    481     SkBitmap fBitmap;
    482     int      fLeft;
    483     int      fTop;
    484     SkPaint  fPaint;
    485     SkPaint* fPaintPtr;
    486 
    487     typedef SkDrawCommand INHERITED;
    488 };
    489 
    490 class SkDrawVerticesCommand : public SkDrawCommand {
    491 public:
    492     SkDrawVerticesCommand(SkCanvas::VertexMode vmode, int vertexCount,
    493                           const SkPoint vertices[], const SkPoint texs[],
    494                           const SkColor colors[], SkXfermode* xfermode,
    495                           const uint16_t indices[], int indexCount,
    496                           const SkPaint& paint);
    497     virtual ~SkDrawVerticesCommand();
    498     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    499 private:
    500     SkCanvas::VertexMode fVmode;
    501     int         fVertexCount;
    502     SkPoint*    fVertices;
    503     SkPoint*    fTexs;
    504     SkColor*    fColors;
    505     SkXfermode* fXfermode;
    506     uint16_t*   fIndices;
    507     int         fIndexCount;
    508     SkPaint     fPaint;
    509 
    510     typedef SkDrawCommand INHERITED;
    511 };
    512 
    513 class SkRotateCommand : public SkDrawCommand {
    514 public:
    515     SkRotateCommand(SkScalar degrees);
    516     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    517 private:
    518     SkScalar fDegrees;
    519 
    520     typedef SkDrawCommand INHERITED;
    521 };
    522 
    523 class SkSaveCommand : public SkDrawCommand {
    524 public:
    525     SkSaveCommand(SkCanvas::SaveFlags flags);
    526     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    527     virtual void trackSaveState(int* state) SK_OVERRIDE;
    528     virtual Action action() const SK_OVERRIDE { return kPushLayer_Action; }
    529 private:
    530     SkCanvas::SaveFlags fFlags;
    531 
    532     typedef SkDrawCommand INHERITED;
    533 };
    534 
    535 class SkSaveLayerCommand : public SkDrawCommand {
    536 public:
    537     SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint,
    538                        SkCanvas::SaveFlags flags);
    539     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    540     virtual void vizExecute(SkCanvas* canvas) SK_OVERRIDE;
    541     virtual void trackSaveState(int* state) SK_OVERRIDE;
    542     virtual Action action() const SK_OVERRIDE{ return kPushLayer_Action; }
    543     virtual void setActive(bool active) SK_OVERRIDE { fActive = active; }
    544     virtual bool active() const SK_OVERRIDE { return fActive; }
    545 
    546     const SkPaint* paint() const { return fPaintPtr; }
    547 
    548 private:
    549     SkRect              fBounds;
    550     SkPaint             fPaint;
    551     SkPaint*            fPaintPtr;
    552     SkCanvas::SaveFlags fFlags;
    553 
    554     bool                fActive;
    555 
    556     typedef SkDrawCommand INHERITED;
    557 };
    558 
    559 class SkScaleCommand : public SkDrawCommand {
    560 public:
    561     SkScaleCommand(SkScalar sx, SkScalar sy);
    562     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    563 
    564     SkScalar x() const { return fSx; }
    565     SkScalar y() const { return fSy; }
    566 
    567 private:
    568     SkScalar fSx;
    569     SkScalar fSy;
    570 
    571     typedef SkDrawCommand INHERITED;
    572 };
    573 
    574 class SkSetMatrixCommand : public SkDrawCommand {
    575 public:
    576     SkSetMatrixCommand(const SkMatrix& matrix);
    577     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    578 private:
    579     SkMatrix fMatrix;
    580 
    581     typedef SkDrawCommand INHERITED;
    582 };
    583 
    584 class SkSkewCommand : public SkDrawCommand {
    585 public:
    586     SkSkewCommand(SkScalar sx, SkScalar sy);
    587     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    588 private:
    589     SkScalar fSx;
    590     SkScalar fSy;
    591 
    592     typedef SkDrawCommand INHERITED;
    593 };
    594 
    595 class SkTranslateCommand : public SkDrawCommand {
    596 public:
    597     SkTranslateCommand(SkScalar dx, SkScalar dy);
    598     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    599 
    600     SkScalar x() const { return fDx; }
    601     SkScalar y() const { return fDy; }
    602 
    603 private:
    604     SkScalar fDx;
    605     SkScalar fDy;
    606 
    607     typedef SkDrawCommand INHERITED;
    608 };
    609 
    610 class SkPushCullCommand : public SkDrawCommand {
    611 public:
    612     SkPushCullCommand(const SkRect&);
    613     virtual void execute(SkCanvas*) SK_OVERRIDE;
    614     virtual void vizExecute(SkCanvas* canvas) SK_OVERRIDE;
    615     virtual Action action() const { return kPushCull_Action; }
    616     virtual void setActive(bool active) { fActive = active; }
    617     virtual bool active() const { return fActive; }
    618 private:
    619     SkRect fCullRect;
    620     bool   fActive;
    621 
    622     typedef SkDrawCommand INHERITED;
    623 };
    624 
    625 class SkPopCullCommand : public SkDrawCommand {
    626 public:
    627     SkPopCullCommand();
    628     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
    629     virtual Action action() const { return kPopCull_Action; }
    630 private:
    631     typedef SkDrawCommand INHERITED;
    632 };
    633 
    634 #endif
    635