Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright 2013 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 "SkLuaCanvas.h"
      9 #include "SkLua.h"
     10 
     11 extern "C" {
     12     #include "lua.h"
     13     #include "lauxlib.h"
     14 }
     15 
     16 class AutoCallLua : public SkLua {
     17 public:
     18     AutoCallLua(lua_State* L, const char func[], const char verb[]) : INHERITED(L) {
     19         lua_getglobal(L, func);
     20         if (!lua_isfunction(L, -1)) {
     21             int t = lua_type(L, -1);
     22             SkDebugf("--- expected function %d\n", t);
     23         }
     24 
     25         lua_newtable(L);
     26         this->pushString(verb, "verb");
     27     }
     28 
     29     ~AutoCallLua() {
     30         lua_State* L = this->get();
     31         if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
     32             SkDebugf("lua err: %s\n", lua_tostring(L, -1));
     33         }
     34         lua_settop(L, -1);
     35     }
     36 
     37     void pushEncodedText(SkPaint::TextEncoding, const void*, size_t);
     38 
     39 private:
     40     typedef SkLua INHERITED;
     41 };
     42 
     43 #define AUTO_LUA(verb)  AutoCallLua lua(fL, fFunc.c_str(), verb)
     44 
     45 
     46 ///////////////////////////////////////////////////////////////////////////////
     47 
     48 void AutoCallLua::pushEncodedText(SkPaint::TextEncoding enc, const void* text,
     49                                   size_t length) {
     50     switch (enc) {
     51         case SkPaint::kUTF8_TextEncoding:
     52             this->pushString((const char*)text, length, "text");
     53             break;
     54         case SkPaint::kUTF16_TextEncoding: {
     55             SkString str;
     56             str.setUTF16((const uint16_t*)text, length);
     57             this->pushString(str, "text");
     58         } break;
     59         case SkPaint::kGlyphID_TextEncoding:
     60             this->pushArrayU16((const uint16_t*)text, SkToInt(length >> 1),
     61                                "glyphs");
     62             break;
     63         case SkPaint::kUTF32_TextEncoding:
     64             break;
     65     }
     66 }
     67 
     68 ///////////////////////////////////////////////////////////////////////////////
     69 
     70 void SkLuaCanvas::pushThis() {
     71     SkLua(fL).pushCanvas(this);
     72 }
     73 
     74 ///////////////////////////////////////////////////////////////////////////////
     75 
     76 SkLuaCanvas::SkLuaCanvas(int width, int height, lua_State* L, const char func[])
     77     : INHERITED(width, height)
     78     , fL(L)
     79     , fFunc(func) {
     80 }
     81 
     82 SkLuaCanvas::~SkLuaCanvas() {}
     83 
     84 void SkLuaCanvas::willSave() {
     85     AUTO_LUA("save");
     86     this->INHERITED::willSave();
     87 }
     88 
     89 SkCanvas::SaveLayerStrategy SkLuaCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
     90     AUTO_LUA("saveLayer");
     91     if (rec.fBounds) {
     92         lua.pushRect(*rec.fBounds, "bounds");
     93     }
     94     if (rec.fPaint) {
     95         lua.pushPaint(*rec.fPaint, "paint");
     96     }
     97 
     98     (void)this->INHERITED::getSaveLayerStrategy(rec);
     99     // No need for a layer.
    100     return kNoLayer_SaveLayerStrategy;
    101 }
    102 
    103 void SkLuaCanvas::willRestore() {
    104     AUTO_LUA("restore");
    105     this->INHERITED::willRestore();
    106 }
    107 
    108 void SkLuaCanvas::didConcat(const SkMatrix& matrix) {
    109     switch (matrix.getType()) {
    110         case SkMatrix::kTranslate_Mask: {
    111             AUTO_LUA("translate");
    112             lua.pushScalar(matrix.getTranslateX(), "dx");
    113             lua.pushScalar(matrix.getTranslateY(), "dy");
    114             break;
    115         }
    116         case SkMatrix::kScale_Mask: {
    117             AUTO_LUA("scale");
    118             lua.pushScalar(matrix.getScaleX(), "sx");
    119             lua.pushScalar(matrix.getScaleY(), "sy");
    120             break;
    121         }
    122         default: {
    123             AUTO_LUA("concat");
    124             // pushMatrix added in https://codereview.chromium.org/203203004/
    125             // Doesn't seem to have ever been working correctly since added
    126             // lua.pushMatrix(matrix);
    127             break;
    128         }
    129     }
    130 
    131     this->INHERITED::didConcat(matrix);
    132 }
    133 
    134 void SkLuaCanvas::didSetMatrix(const SkMatrix& matrix) {
    135     this->INHERITED::didSetMatrix(matrix);
    136 }
    137 
    138 void SkLuaCanvas::onClipRect(const SkRect& r, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
    139     AUTO_LUA("clipRect");
    140     lua.pushRect(r, "rect");
    141     lua.pushBool(kSoft_ClipEdgeStyle == edgeStyle, "aa");
    142     this->INHERITED::onClipRect(r, op, edgeStyle);
    143 }
    144 
    145 void SkLuaCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
    146     AUTO_LUA("clipRRect");
    147     lua.pushRRect(rrect, "rrect");
    148     lua.pushBool(kSoft_ClipEdgeStyle == edgeStyle, "aa");
    149     this->INHERITED::onClipRRect(rrect, op, edgeStyle);
    150 }
    151 
    152 void SkLuaCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
    153     AUTO_LUA("clipPath");
    154     lua.pushPath(path, "path");
    155     lua.pushBool(kSoft_ClipEdgeStyle == edgeStyle, "aa");
    156     this->INHERITED::onClipPath(path, op, edgeStyle);
    157 }
    158 
    159 void SkLuaCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
    160     AUTO_LUA("clipRegion");
    161     this->INHERITED::onClipRegion(deviceRgn, op);
    162 }
    163 
    164 void SkLuaCanvas::onDrawPaint(const SkPaint& paint) {
    165     AUTO_LUA("drawPaint");
    166     lua.pushPaint(paint, "paint");
    167 }
    168 
    169 void SkLuaCanvas::onDrawPoints(PointMode mode, size_t count,
    170                                const SkPoint pts[], const SkPaint& paint) {
    171     AUTO_LUA("drawPoints");
    172     lua.pushArrayPoint(pts, SkToInt(count), "points");
    173     lua.pushPaint(paint, "paint");
    174 }
    175 
    176 void SkLuaCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
    177     AUTO_LUA("drawOval");
    178     lua.pushRect(rect, "rect");
    179     lua.pushPaint(paint, "paint");
    180 }
    181 
    182 void SkLuaCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
    183     AUTO_LUA("drawRect");
    184     lua.pushRect(rect, "rect");
    185     lua.pushPaint(paint, "paint");
    186 }
    187 
    188 void SkLuaCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
    189     AUTO_LUA("drawRRect");
    190     lua.pushRRect(rrect, "rrect");
    191     lua.pushPaint(paint, "paint");
    192 }
    193 
    194 void SkLuaCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
    195                                const SkPaint& paint) {
    196     AUTO_LUA("drawDRRect");
    197     lua.pushRRect(outer, "outer");
    198     lua.pushRRect(inner, "inner");
    199     lua.pushPaint(paint, "paint");
    200 }
    201 
    202 void SkLuaCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
    203     AUTO_LUA("drawPath");
    204     lua.pushPath(path, "path");
    205     lua.pushPaint(paint, "paint");
    206 }
    207 
    208 void SkLuaCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
    209                                const SkPaint* paint) {
    210     AUTO_LUA("drawBitmap");
    211     if (paint) {
    212         lua.pushPaint(*paint, "paint");
    213     }
    214 }
    215 
    216 void SkLuaCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
    217                                    const SkPaint* paint, SrcRectConstraint) {
    218     AUTO_LUA("drawBitmapRect");
    219     if (paint) {
    220         lua.pushPaint(*paint, "paint");
    221     }
    222 }
    223 
    224 void SkLuaCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
    225                                    const SkPaint* paint) {
    226     AUTO_LUA("drawBitmapNine");
    227     if (paint) {
    228         lua.pushPaint(*paint, "paint");
    229     }
    230 }
    231 
    232 void SkLuaCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) {
    233     AUTO_LUA("drawImage");
    234     if (paint) {
    235         lua.pushPaint(*paint, "paint");
    236     }
    237 }
    238 
    239 void SkLuaCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
    240                                   const SkPaint* paint, SrcRectConstraint) {
    241     AUTO_LUA("drawImageRect");
    242     if (paint) {
    243         lua.pushPaint(*paint, "paint");
    244     }
    245 }
    246 
    247 void SkLuaCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
    248                              const SkPaint& paint) {
    249     AUTO_LUA("drawText");
    250     lua.pushEncodedText(paint.getTextEncoding(), text, byteLength);
    251     lua.pushPaint(paint, "paint");
    252 }
    253 
    254 void SkLuaCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
    255                                 const SkPaint& paint) {
    256     AUTO_LUA("drawPosText");
    257     lua.pushEncodedText(paint.getTextEncoding(), text, byteLength);
    258     lua.pushPaint(paint, "paint");
    259 }
    260 
    261 void SkLuaCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
    262                                  SkScalar constY, const SkPaint& paint) {
    263     AUTO_LUA("drawPosTextH");
    264     lua.pushEncodedText(paint.getTextEncoding(), text, byteLength);
    265     lua.pushPaint(paint, "paint");
    266 }
    267 
    268 void SkLuaCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
    269                                    const SkMatrix* matrix, const SkPaint& paint) {
    270     AUTO_LUA("drawTextOnPath");
    271     lua.pushPath(path, "path");
    272     lua.pushEncodedText(paint.getTextEncoding(), text, byteLength);
    273     lua.pushPaint(paint, "paint");
    274 }
    275 
    276 void SkLuaCanvas::onDrawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y,
    277                                  const SkPaint &paint) {
    278     AUTO_LUA("drawTextBlob");
    279     lua.pushTextBlob(blob, "blob");
    280     lua.pushScalar(x, "x");
    281     lua.pushScalar(y, "y");
    282     lua.pushPaint(paint, "paint");
    283 }
    284 
    285 void SkLuaCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
    286                                 const SkPaint* paint) {
    287     AUTO_LUA("drawPicture");
    288     // call through so we can see the nested picture ops
    289     this->INHERITED::onDrawPicture(picture, matrix, paint);
    290 }
    291 
    292 void SkLuaCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
    293                                  const SkPoint vertices[], const SkPoint texs[],
    294                                  const SkColor colors[], SkXfermode* xmode,
    295                                  const uint16_t indices[], int indexCount,
    296                                  const SkPaint& paint) {
    297     AUTO_LUA("drawVertices");
    298     lua.pushPaint(paint, "paint");
    299 }
    300