| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917 |
- #include "platform/CCCanvasRenderingContext2D.h"
- #include "base/ccTypes.h"
- #include "base/csscolorparser.hpp"
- #include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
- #include "cocos/scripting/js-bindings/manual/jsb_platform.h"
- #include "platform/CCFileUtils.h"
- #include <regex>
- using namespace cocos2d;
- enum class CanvasTextAlign {
- LEFT,
- CENTER,
- RIGHT
- };
- enum class CanvasTextBaseline {
- TOP,
- MIDDLE,
- BOTTOM
- };
- namespace {
- void fillRectWithColor(uint8_t* buf, uint32_t totalWidth, uint32_t totalHeight, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
- {
- assert(x + width <= totalWidth);
- assert(y + height <= totalHeight);
- uint32_t y0 = y;
- uint32_t y1 = y + height;
- uint8_t* p;
- for (uint32_t offsetY = y0; offsetY < y1; ++offsetY)
- {
- for (uint32_t offsetX = x; offsetX < (x + width); ++offsetX)
- {
- p = buf + (totalWidth * offsetY + offsetX) * 4;
- *p++ = r;
- *p++ = g;
- *p++ = b;
- *p++ = a;
- }
- }
- }
- }
- class CanvasRenderingContext2DImpl
- {
- public:
- CanvasRenderingContext2DImpl() : _DC(nullptr)
- , _bmp(nullptr)
- , _font((HFONT)GetStockObject(DEFAULT_GUI_FONT))
- , _wnd(nullptr)
- , _savedDC(0)
- {
- _wnd = nullptr;
- HDC hdc = GetDC(_wnd);
- _DC = CreateCompatibleDC(hdc);
- ReleaseDC(_wnd, hdc);
- }
- ~CanvasRenderingContext2DImpl()
- {
- _deleteBitmap();
- _removeCustomFont();
- if (_DC)
- DeleteDC(_DC);
- }
- void recreateBuffer(float w, float h)
- {
- _bufferWidth = w;
- _bufferHeight = h;
- if (_bufferWidth < 1.0f || _bufferHeight < 1.0f)
- {
- _deleteBitmap();
- return;
- }
- int textureSize = _bufferWidth * _bufferHeight * 4;
- uint8_t* data = (uint8_t*)malloc(sizeof(uint8_t) * textureSize);
- memset(data, 0x00, textureSize);
- _imageData.fastSet(data, textureSize);
- _prepareBitmap(_bufferWidth, _bufferHeight);
- }
- void beginPath()
- {
- // called: set_lineWidth() -> beginPath() -> moveTo() -> lineTo() -> stroke(), when draw line
- _hpen = CreatePen(PS_SOLID, _lineWidth, RGB(255, 255, 255));
- // the return value of SelectObject is a handle to the object being replaced, so we should delete them to avoid memory leak
- HGDIOBJ hOldPen = SelectObject(_DC, _hpen);
- HGDIOBJ hOldBmp = SelectObject(_DC, _bmp);
- DeleteObject(hOldPen);
- DeleteObject(hOldBmp);
- SetBkMode(_DC, TRANSPARENT);
- }
- void closePath()
- {
- }
- void moveTo(float x, float y)
- {
- MoveToEx(_DC, x, -(y - _bufferHeight - _fontSize), nullptr);
- }
- void lineTo(float x, float y)
- {
- LineTo(_DC, x, -(y - _bufferHeight - _fontSize));
- }
- void stroke()
- {
- DeleteObject(_hpen);
- if (_bufferWidth < 1.0f || _bufferHeight < 1.0f)
- return;
- _fillTextureData();
- }
- void saveContext()
- {
- _savedDC = SaveDC(_DC);
- }
- void restoreContext()
- {
- BOOL ret = RestoreDC(_DC, _savedDC);
- if (0 == ret)
- {
- SE_LOGD("CanvasRenderingContext2DImpl restore context failed.\n");
- }
- }
- void clearRect(float x, float y, float w, float h)
- {
- if (_bufferWidth < 1.0f || _bufferHeight < 1.0f)
- return;
- if (_imageData.isNull())
- return;
- recreateBuffer(w, h);
- }
- void fillRect(float x, float y, float w, float h)
- {
- if (_bufferWidth < 1.0f || _bufferHeight < 1.0f)
- return;
- //not filled all Bits in buffer? the buffer length is _bufferWidth * _bufferHeight * 4, but it filled _bufferWidth * _bufferHeight * 3?
- uint8_t* buffer = _imageData.getBytes();
- if (buffer)
- {
- uint8_t r = _fillStyle.r * 255.0f;
- uint8_t g = _fillStyle.g * 255.0f;
- uint8_t b = _fillStyle.b * 255.0f;
- uint8_t a = _fillStyle.a * 255.0f;
- fillRectWithColor(buffer, (uint32_t)_bufferWidth, (uint32_t)_bufferHeight, (uint32_t)x, (uint32_t)y, (uint32_t)w, (uint32_t)h, r, g, b, a);
- }
- }
- void fillText(const std::string& text, float x, float y, float maxWidth)
- {
- if (text.empty() || _bufferWidth < 1.0f || _bufferHeight < 1.0f)
- return;
- SIZE textSize = { 0, 0 };
- Point offsetPoint = _convertDrawPoint(Point(x, y), text);
- _drawText(text, (int)offsetPoint.x, (int)offsetPoint.y);
- _fillTextureData();
- }
- void strokeText(const std::string& text, float x, float y, float maxWidth)
- {
- if (text.empty() || _bufferWidth < 1.0f || _bufferHeight < 1.0f)
- return;
- // REFINE
- }
- cocos2d::Size measureText(const std::string& text)
- {
- if (text.empty())
- return Size(0.0f, 0.0f);
- int bufferLen = 0;
- wchar_t * pwszBuffer = _utf8ToUtf16(text, &bufferLen);
- SIZE size = _sizeWithText(pwszBuffer, bufferLen);
- //SE_LOGD("CanvasRenderingContext2DImpl::measureText: %s, %d, %d\n", text.c_str(), size.cx, size.cy);
- CC_SAFE_DELETE_ARRAY(pwszBuffer);
- return Size(size.cx, size.cy);
- }
- void updateFont(const std::string& fontName, float fontSize, bool bold = false)
- {
- do
- {
- _fontName = fontName;
- _fontSize = fontSize;
- std::string fontPath;
- LOGFONTA tFont = { 0 };
- if (!_fontName.empty())
- {
- // firstly, try to create font from ttf file
- const auto& fontInfoMap = getFontFamilyNameMap();
- auto iter = fontInfoMap.find(_fontName);
- if (iter != fontInfoMap.end())
- {
- fontPath = iter->second;
- std::string tmpFontPath = fontPath;
- int nFindPos = tmpFontPath.rfind("/");
- tmpFontPath = &tmpFontPath[nFindPos + 1];
- nFindPos = tmpFontPath.rfind(".");
- // IDEA: draw ttf failed if font file name not equal font face name
- // for example: "DejaVuSansMono-Oblique" not equal "DejaVu Sans Mono" when using DejaVuSansMono-Oblique.ttf
- _fontName = tmpFontPath.substr(0, nFindPos);
- }
- else
- {
- auto nFindPos = fontName.rfind("/");
- if (nFindPos != fontName.npos)
- {
- if (fontName.length() == nFindPos + 1)
- {
- _fontName = "";
- }
- else
- {
- _fontName = &_fontName[nFindPos + 1];
- }
- }
- }
- tFont.lfCharSet = DEFAULT_CHARSET;
- strcpy_s(tFont.lfFaceName, LF_FACESIZE, _fontName.c_str());
- }
- if (_fontSize)
- tFont.lfHeight = -_fontSize;
- if (bold)
- tFont.lfWeight = FW_BOLD;
- else
- tFont.lfWeight = FW_NORMAL;
- // disable Cleartype
- tFont.lfQuality = ANTIALIASED_QUALITY;
- // delete old font
- _removeCustomFont();
- if (fontPath.size() > 0)
- {
- _curFontPath = fontPath;
- wchar_t * pwszBuffer = _utf8ToUtf16(_curFontPath);
- if (pwszBuffer)
- {
- if (AddFontResource(pwszBuffer))
- {
- SendMessage(_wnd, WM_FONTCHANGE, 0, 0);
- }
- delete[] pwszBuffer;
- pwszBuffer = nullptr;
- }
- }
- // create new font
- _font = CreateFontIndirectA(&tFont);
- if (!_font)
- {
- // create failed, use default font
- SE_LOGE("Failed to create custom font(font name: %s, font size: %f), use default font.\n",
- _fontName.c_str(), fontSize);
- break;
- }
- else
- {
- SelectObject(_DC, _font);
- SendMessage(_wnd, WM_FONTCHANGE, 0, 0);
- }
- } while (0);
- }
- void setTextAlign(CanvasTextAlign align)
- {
- _textAlign = align;
- }
- void setTextBaseline(CanvasTextBaseline baseline)
- {
- _textBaseLine = baseline;
- }
- void setFillStyle(float r, float g, float b, float a)
- {
- _fillStyle.r = r;
- _fillStyle.g = g;
- _fillStyle.b = b;
- _fillStyle.a = a;
- }
- void setStrokeStyle(float r, float g, float b, float a)
- {
- _strokeStyle.r = r;
- _strokeStyle.g = g;
- _strokeStyle.b = b;
- _strokeStyle.a = a;
- }
- void setLineWidth(float lineWidth)
- {
- _lineWidth = lineWidth;
- }
- void setPremultiply(bool multiply)
- {
- _premultiply = multiply;
- }
- const Data& getDataRef() const
- {
- return _imageData;
- }
- HDC _DC;
- HBITMAP _bmp;
- private:
- Data _imageData;
- HFONT _font;
- HWND _wnd;
- HPEN _hpen;
- PAINTSTRUCT _paintStruct;
- std::string _curFontPath;
- int _savedDC;
- float _lineWidth = 0.0f;
- float _bufferWidth = 0.0f;
- float _bufferHeight = 0.0f;
- bool _premultiply = true;
- std::string _fontName;
- int _fontSize;
- SIZE _textSize;
- CanvasTextAlign _textAlign;
- CanvasTextBaseline _textBaseLine;
- cocos2d::Color4F _fillStyle;
- cocos2d::Color4F _strokeStyle;
- TEXTMETRIC _tm;
- // change utf-8 string to utf-16, pRetLen is the string length after changing
- wchar_t * _utf8ToUtf16(const std::string& str, int * pRetLen = nullptr)
- {
- wchar_t * pwszBuffer = nullptr;
- do
- {
- if (str.empty())
- {
- break;
- }
- int nLen = str.size();
- int nBufLen = nLen + 1;
- pwszBuffer = new wchar_t[nBufLen];
- CC_BREAK_IF(!pwszBuffer);
- memset(pwszBuffer, 0, sizeof(wchar_t) * nBufLen);
- // str.size() not equal actuallyLen for Chinese char
- int actuallyLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), nLen, pwszBuffer, nBufLen);
- // SE_LOGE("_utf8ToUtf16, str:%s, strLen:%d, retLen:%d\n", str.c_str(), str.size(), actuallyLen);
- if (pRetLen != nullptr) {
- *pRetLen = actuallyLen;
- }
- } while (0);
- return pwszBuffer;
- }
- void _removeCustomFont()
- {
- HFONT hDefFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
- if (hDefFont != _font)
- {
- DeleteObject(SelectObject(_DC, hDefFont));
- }
- // release temp font resource
- if (_curFontPath.size() > 0)
- {
- wchar_t * pwszBuffer = _utf8ToUtf16(_curFontPath);
- if (pwszBuffer)
- {
- RemoveFontResource(pwszBuffer);
- SendMessage(_wnd, WM_FONTCHANGE, 0, 0);
- delete[] pwszBuffer;
- pwszBuffer = nullptr;
- }
- _curFontPath.clear();
- }
- }
- // x, y offset value
- int _drawText(const std::string& text, int x, int y)
- {
- int nRet = 0;
- wchar_t * pwszBuffer = nullptr;
- do
- {
- CC_BREAK_IF(text.empty());
- DWORD dwFmt = DT_SINGLELINE | DT_NOPREFIX;
- int bufferLen = 0;
- pwszBuffer = _utf8ToUtf16(text, &bufferLen);
- SIZE newSize = _sizeWithText(pwszBuffer, bufferLen);
- _textSize = newSize;
- RECT rcText = { 0 };
- rcText.right = newSize.cx;
- rcText.bottom = newSize.cy;
- LONG offsetX = x;
- LONG offsetY = y;
- if (offsetX || offsetY)
- {
- OffsetRect(&rcText, offsetX, offsetY);
- }
- // SE_LOGE("_drawText text,%s size: (%d, %d) offset after convert: (%d, %d) \n", text.c_str(), newSize.cx, newSize.cy, offsetX, offsetY);
- SetBkMode(_DC, TRANSPARENT);
- SetTextColor(_DC, RGB(255, 255, 255)); // white color
- // draw text
- nRet = DrawTextW(_DC, pwszBuffer, bufferLen, &rcText, dwFmt);
- } while (0);
- CC_SAFE_DELETE_ARRAY(pwszBuffer);
- return nRet;
- }
- SIZE _sizeWithText(const wchar_t * pszText, int nLen)
- {
- SIZE tRet = { 0 };
- do
- {
- CC_BREAK_IF(!pszText || nLen <= 0);
- RECT rc = { 0, 0, 0, 0 };
- DWORD dwCalcFmt = DT_CALCRECT | DT_NOPREFIX;
- // measure text size
- DrawTextW(_DC, pszText, nLen, &rc, dwCalcFmt);
- tRet.cx = rc.right;
- tRet.cy = rc.bottom;
- } while (0);
- return tRet;
- }
- void _prepareBitmap(int nWidth, int nHeight)
- {
- // release bitmap
- _deleteBitmap();
- if (nWidth > 0 && nHeight > 0)
- {
- _bmp = CreateBitmap(nWidth, nHeight, 1, 32, nullptr);
- SelectObject(_DC, _bmp);
- }
- }
- void _deleteBitmap()
- {
- if (_bmp)
- {
- DeleteObject(_bmp);
- _bmp = nullptr;
- }
- }
- void _fillTextureData()
- {
- do
- {
- int dataLen = _bufferWidth * _bufferHeight * 4;
- unsigned char* dataBuf = (unsigned char*)malloc(sizeof(unsigned char) * dataLen);
- CC_BREAK_IF(!dataBuf);
- unsigned char* imageBuf = _imageData.getBytes();
- CC_BREAK_IF(!imageBuf);
- struct
- {
- BITMAPINFOHEADER bmiHeader;
- int mask[4];
- } bi = { 0 };
- bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
- CC_BREAK_IF(!GetDIBits(_DC, _bmp, 0, 0,
- nullptr, (LPBITMAPINFO)&bi, DIB_RGB_COLORS));
- // copy pixel data
- bi.bmiHeader.biHeight = (bi.bmiHeader.biHeight > 0) ? -bi.bmiHeader.biHeight : bi.bmiHeader.biHeight;
- GetDIBits(_DC, _bmp, 0, _bufferHeight, dataBuf,
- (LPBITMAPINFO)&bi, DIB_RGB_COLORS);
- uint8_t r = _fillStyle.r * 255;
- uint8_t g = _fillStyle.g * 255;
- uint8_t b = _fillStyle.b * 255;
- uint8_t a = _fillStyle.a;
- COLORREF textColor = (b << 16 | g << 8 | r) & 0x00ffffff;
- COLORREF * pPixel = nullptr;
- COLORREF * pImage = nullptr;
- if (_premultiply)
- {
- uint8_t dirtyValue = 0;
- for (int y = 0; y < _bufferHeight; ++y)
- {
- pPixel = (COLORREF *)dataBuf + y * (int)_bufferWidth;
- pImage = (COLORREF *)imageBuf + y * (int)_bufferWidth;
- for (int x = 0; x < _bufferWidth; ++x)
- {
- COLORREF& clr = *pPixel;
- COLORREF& val = *pImage;
- dirtyValue = GetRValue(clr);
- // "dirtyValue > 0" means pixel was covered when drawing text
- if (dirtyValue > 0)
- {
- // r = _fillStyle.r * 255 * (dirtyValue / 255) * alpha;
- r = _fillStyle.r * dirtyValue * a;
- g = _fillStyle.g * dirtyValue * a;
- b = _fillStyle.b * dirtyValue * a;
- textColor = (b << 16 | g << 8 | r) & 0x00ffffff;
- val = ((BYTE)(dirtyValue * a) << 24) | textColor;
- }
- ++pPixel;
- ++pImage;
- }
- }
- }
- else
- {
- for (int y = 0; y < _bufferHeight; ++y)
- {
- pPixel = (COLORREF *)dataBuf + y * (int)_bufferWidth;
- pImage = (COLORREF *)imageBuf + y * (int)_bufferWidth;
- for (int x = 0; x < _bufferWidth; ++x)
- {
- COLORREF& clr = *pPixel;
- COLORREF& val = *pImage;
- // Because text is drawn in white color, and background color is black,
- // so the red value is equal to alpha value. And we should keep this value
- // as it includes anti-atlas information.
- uint8_t alpha = GetRValue(clr);
- if (alpha > 0)
- {
- val = (alpha << 24) | textColor;
- }
-
- ++pPixel;
- ++pImage;
- }
- }
- }
-
- free(dataBuf);
- } while (0);
- }
- Point _convertDrawPoint(Point point, std::string text) {
- Size textSize = measureText(text);
- if (_textAlign == CanvasTextAlign::CENTER)
- {
- point.x -= textSize.width / 2.0f;
- }
- else if (_textAlign == CanvasTextAlign::RIGHT)
- {
- point.x -= textSize.width;
- }
- if (_textBaseLine == CanvasTextBaseline::TOP)
- {
- point.y += _fontSize;
- }
- else if (_textBaseLine == CanvasTextBaseline::MIDDLE)
- {
- point.y += _fontSize / 2.0f;
- }
- // Since the web platform cannot get the baseline of the font, an additive offset is performed for all platforms.
- // That's why we should add baseline back again on other platforms
- GetTextMetrics(_DC, &_tm);
- point.y -= _tm.tmAscent;
- return point;
- }
- };
- NS_CC_BEGIN
- CanvasGradient::CanvasGradient()
- {
- //SE_LOGD("CanvasGradient constructor: %p\n", this);
- }
- CanvasGradient::~CanvasGradient()
- {
- //SE_LOGD("CanvasGradient destructor: %p\n", this);
- }
- void CanvasGradient::addColorStop(float offset, const std::string& color)
- {
- //SE_LOGD("CanvasGradient::addColorStop: %p\n", this);
- }
- // CanvasRenderingContext2D
- CanvasRenderingContext2D::CanvasRenderingContext2D(float width, float height)
- : __width(width)
- , __height(height)
- {
- //SE_LOGD("CanvasRenderingContext2D constructor: %p, width: %f, height: %f\n", this, width, height);
- _impl = new CanvasRenderingContext2DImpl();
- recreateBufferIfNeeded();
- }
- CanvasRenderingContext2D::~CanvasRenderingContext2D()
- {
- //SE_LOGD("CanvasRenderingContext2D destructor: %p\n", this);
- delete _impl;
- }
- void CanvasRenderingContext2D::recreateBufferIfNeeded()
- {
- if (_isBufferSizeDirty)
- {
- _isBufferSizeDirty = false;
- //SE_LOGD("Recreate buffer %p, w: %f, h:%f\n", this, __width, __height);
- _impl->recreateBuffer(__width, __height);
- if (_canvasBufferUpdatedCB != nullptr)
- _canvasBufferUpdatedCB(_impl->getDataRef());
- }
- }
- void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
- {
- //SE_LOGD("CanvasRenderingContext2D::clearRect: %p, %f, %f, %f, %f\n", this, x, y, width, height);
- recreateBufferIfNeeded();
- _impl->clearRect(x, y, width, height);
- }
- void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height)
- {
- recreateBufferIfNeeded();
- _impl->fillRect(x, y, width, height);
- if (_canvasBufferUpdatedCB != nullptr)
- _canvasBufferUpdatedCB(_impl->getDataRef());
- }
- void CanvasRenderingContext2D::fillText(const std::string& text, float x, float y, float maxWidth)
- {
- //SE_LOGD("CanvasRenderingContext2D::fillText: %s, offset: (%f, %f), %f\n", text.c_str(), x, y, maxWidth);
- if (text.empty())
- return;
- recreateBufferIfNeeded();
- _impl->fillText(text, x, y, maxWidth);
- if (_canvasBufferUpdatedCB != nullptr)
- _canvasBufferUpdatedCB(_impl->getDataRef());
- }
- void CanvasRenderingContext2D::strokeText(const std::string& text, float x, float y, float maxWidth)
- {
- //SE_LOGD("CanvasRenderingContext2D::strokeText: %s, %f, %f, %f\n", text.c_str(), x, y, maxWidth);
- if (text.empty())
- return;
- recreateBufferIfNeeded();
- _impl->strokeText(text, x, y, maxWidth);
- if (_canvasBufferUpdatedCB != nullptr)
- _canvasBufferUpdatedCB(_impl->getDataRef());
- }
- cocos2d::Size CanvasRenderingContext2D::measureText(const std::string& text)
- {
- //SE_LOGD("CanvasRenderingContext2D::measureText: %s\n", text.c_str());
- return _impl->measureText(text);
- }
- CanvasGradient* CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1)
- {
- return nullptr;
- }
- void CanvasRenderingContext2D::save()
- {
- //SE_LOGD("CanvasRenderingContext2D::save\n");
- _impl->saveContext();
- }
- void CanvasRenderingContext2D::beginPath()
- {
- //SE_LOGD("\n-----------begin------------------\nCanvasRenderingContext2D::beginPath\n");
- _impl->beginPath();
- }
- void CanvasRenderingContext2D::closePath()
- {
- //SE_LOGD("CanvasRenderingContext2D::closePath\n");
- _impl->closePath();
- }
- void CanvasRenderingContext2D::moveTo(float x, float y)
- {
- //SE_LOGD("CanvasRenderingContext2D::moveTo\n");
- _impl->moveTo(x, y);
- }
- void CanvasRenderingContext2D::lineTo(float x, float y)
- {
- //SE_LOGD("CanvasRenderingContext2D::lineTo\n");
- _impl->lineTo(x, y);
- }
- void CanvasRenderingContext2D::stroke()
- {
- //SE_LOGD("CanvasRenderingContext2D::stroke\n");
- _impl->stroke();
- if (_canvasBufferUpdatedCB != nullptr)
- _canvasBufferUpdatedCB(_impl->getDataRef());
- }
- void CanvasRenderingContext2D::restore()
- {
- //SE_LOGD("CanvasRenderingContext2D::restore\n");
- _impl->restoreContext();
- }
- void CanvasRenderingContext2D::setCanvasBufferUpdatedCallback(const CanvasBufferUpdatedCallback& cb)
- {
- _canvasBufferUpdatedCB = cb;
- }
- void CanvasRenderingContext2D::setPremultiply(bool multiply)
- {
- _impl->setPremultiply(_premultiply);
- }
- void CanvasRenderingContext2D::set__width(float width)
- {
- //SE_LOGD("CanvasRenderingContext2D::set__width: %f\n", width);
- __width = width;
- _isBufferSizeDirty = true;
- recreateBufferIfNeeded();
- }
- void CanvasRenderingContext2D::set__height(float height)
- {
- //SE_LOGD("CanvasRenderingContext2D::set__height: %f\n", height);
- __height = height;
- _isBufferSizeDirty = true;
- recreateBufferIfNeeded();
- }
- void CanvasRenderingContext2D::set_lineWidth(float lineWidth)
- {
- //SE_LOGD("CanvasRenderingContext2D::set_lineWidth %d\n", lineWidth);
- _lineWidth = lineWidth;
- _impl->setLineWidth(lineWidth);
- }
- void CanvasRenderingContext2D::set_lineCap(const std::string& lineCap)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::set_lineJoin(const std::string& lineJoin)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::fill()
- {
- // SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::rect(float x, float y, float w, float h)
- {
- // SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::set_font(const std::string& font)
- {
- if (_font != font)
- {
- _font = font;
- std::string boldStr;
- std::string fontName = "Arial";
- std::string fontSizeStr = "30";
- // support get font name from `60px American` or `60px "American abc-abc_abc"`
- std::regex re("(bold)?\\s*((\\d+)([\\.]\\d+)?)px\\s+([\\w-]+|\"[\\w -]+\"$)");
- std::match_results<std::string::const_iterator> results;
- if (std::regex_search(_font.cbegin(), _font.cend(), results, re))
- {
- boldStr = results[1].str();
- fontSizeStr = results[2].str();
- fontName = results[5].str();
- }
- float fontSize = atof(fontSizeStr.c_str());
- //SE_LOGD("CanvasRenderingContext2D::set_font: %s, Size: %f, isBold: %b\n", fontName.c_str(), fontSize, !boldStr.empty());
- _impl->updateFont(fontName, fontSize, !boldStr.empty());
- }
- }
- void CanvasRenderingContext2D::set_textAlign(const std::string& textAlign)
- {
- //SE_LOGD("CanvasRenderingContext2D::set_textAlign: %s\n", textAlign.c_str());
- if (textAlign == "left")
- {
- _impl->setTextAlign(CanvasTextAlign::LEFT);
- }
- else if (textAlign == "center" || textAlign == "middle")
- {
- _impl->setTextAlign(CanvasTextAlign::CENTER);
- }
- else if (textAlign == "right")
- {
- _impl->setTextAlign(CanvasTextAlign::RIGHT);
- }
- else
- {
- assert(false);
- }
- }
- void CanvasRenderingContext2D::set_textBaseline(const std::string& textBaseline)
- {
- //SE_LOGD("CanvasRenderingContext2D::set_textBaseline: %s\n", textBaseline.c_str());
- if (textBaseline == "top")
- {
- _impl->setTextBaseline(CanvasTextBaseline::TOP);
- }
- else if (textBaseline == "middle")
- {
- _impl->setTextBaseline(CanvasTextBaseline::MIDDLE);
- }
- else if (textBaseline == "bottom" || textBaseline == "alphabetic") //REFINE:, how to deal with alphabetic, currently we handle it as bottom mode.
- {
- _impl->setTextBaseline(CanvasTextBaseline::BOTTOM);
- }
- else
- {
- assert(false);
- }
- }
- void CanvasRenderingContext2D::set_fillStyle(const std::string& fillStyle)
- {
- CSSColorParser::Color color = CSSColorParser::parse(fillStyle);
- _impl->setFillStyle(color.r/255.0f, color.g/255.0f, color.b/255.0f, color.a);
- //SE_LOGD("CanvasRenderingContext2D::set_fillStyle: %s, (%d, %d, %d, %f)\n", fillStyle.c_str(), color.r, color.g, color.b, color.a);
- }
- void CanvasRenderingContext2D::set_strokeStyle(const std::string& strokeStyle)
- {
- CSSColorParser::Color color = CSSColorParser::parse(strokeStyle);
- _impl->setStrokeStyle(color.r/255.0f, color.g/255.0f, color.b/255.0f, color.a);
- }
- void CanvasRenderingContext2D::set_globalCompositeOperation(const std::string& globalCompositeOperation)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::_fillImageData(const Data& imageData, float imageWidth, float imageHeight, float offsetX, float offsetY)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- // transform
- //REFINE:
- void CanvasRenderingContext2D::translate(float x, float y)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::scale(float x, float y)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::rotate(float angle)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::transform(float a, float b, float c, float d, float e, float f)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- void CanvasRenderingContext2D::setTransform(float a, float b, float c, float d, float e, float f)
- {
- //SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
- }
- NS_CC_END
|