feat: merge from new version

This commit is contained in:
jiangweixing 2021-02-23 11:59:55 +08:00
parent d593edbc7f
commit 64d7d080cb
48 changed files with 2261 additions and 1011 deletions

View File

@ -10,6 +10,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fno-exceptions -funwind-tabl
add_definitions(-DFT2_BUILD_LIBRARY)
add_definitions(-DANDROID)
add_definitions(-DCOMMANDBUFFER_2D)
if ((${ANDROID_ARM_NEON}) AND (${ANDROID_ABI} MATCHES arm*))
add_definitions(-DARM_NEON_OPT)
@ -79,7 +80,6 @@ set(SRC_FILES
./src/platform/Android/GPreCompiledShaders.cpp
./src/platform/Android/GSystemFontInformation.cpp
./src/platform/Android/GFontManagerAndroid.cpp
./src/platform/Android/egl/GEGLPbufferContext.cpp
./src/platform/Android/egl/GEGLWindowContext.cpp
@ -97,9 +97,13 @@ set(SRC_FILES
./src/commandbuffer/GCommandBuffer.cpp
./src/commandbuffer/GCommandDecoder.cpp
./src/commandbuffer/GCommandTypes.cpp
./src/webgl/GCommandDecoderWebGL.cpp
./src/webgl/GWebGLRenderContextInner.cpp
./src/webgl/GWebGLRenderContext.cpp
./src/2d/GCommandDecoder2D.cpp
./src/2d/GContext2DRenderContext.cpp
)

View File

@ -0,0 +1,776 @@
/**
* Created by G-Canvas Open Source Team.
* Copyright (c) 2017, Alibaba, Inc. All rights reserved.
*
* This source code is licensed under the Apache Licence 2.0.
* For the full copyright and license information, please view
* the LICENSE file in the root directory of this source tree.
*/
#ifdef COMMANDBUFFER_2D
#include <stdlib.h>
#include <codecvt>
#include <sstream>
#include <string>
#include "../commandbuffer/GCommandDecoder.hpp"
#include "../support/Log.h"
#include "../support/Util.h"
#include "GCommandDecoder2D.hpp"
namespace gcanvas {
typedef void (*GCommand2DFunc)(GContext2DRenderContext*, GCommandBuffer& , GDecodeRes& );
#define CONTEXT2D_SYNC_FUNC_ID_INSERT(NAME) \
mContext2DSyncFuncSet.insert(G2D_FUNC_##NAME);
GCommandDecoder2D::GCommandDecoder2D(GContext2DRenderContext* renderCtx)
: mRenderContext2D(renderCtx)
{
}
GCommandDecoder2D::~GCommandDecoder2D()
{
}
void GCommandDecoder2D::InitCommands()
{
//2d sync api
CONTEXT2D_SYNC_FUNC_ID_INSERT(createImageData_size)
CONTEXT2D_SYNC_FUNC_ID_INSERT(createImageData_data)
CONTEXT2D_SYNC_FUNC_ID_INSERT(createLinearGradient)
CONTEXT2D_SYNC_FUNC_ID_INSERT(createPattern)
CONTEXT2D_SYNC_FUNC_ID_INSERT(createRadialGradient)
CONTEXT2D_SYNC_FUNC_ID_INSERT(getImageData)
CONTEXT2D_SYNC_FUNC_ID_INSERT(getLineDash)
CONTEXT2D_SYNC_FUNC_ID_INSERT(measureText)
}
bool GCommandDecoder2D::Decode(GCommandBuffer& buffer, GDecodeRes& res)
{
static GCommand2DFunc mContext2DFuncs[G2D_FUNC_COUNT] = {
nullptr,
&GCommandDecoder2D::G2D_arc,
&GCommandDecoder2D::G2D_arcTo,
&GCommandDecoder2D::G2D_beginPath,
&GCommandDecoder2D::G2D_bezierCurveTo,
&GCommandDecoder2D::G2D_clearRect,
&GCommandDecoder2D::G2D_clip,
&GCommandDecoder2D::G2D_closePath,
&GCommandDecoder2D::G2D_createImageData_size,
&GCommandDecoder2D::G2D_createImageData_data,
&GCommandDecoder2D::G2D_createLinearGradient,
&GCommandDecoder2D::G2D_createPattern,
&GCommandDecoder2D::G2D_createRadialGradient,
&GCommandDecoder2D::G2D_drawImage_3,
&GCommandDecoder2D::G2D_drawImage_5,
&GCommandDecoder2D::G2D_drawImage_9,
&GCommandDecoder2D::G2D_fill,
&GCommandDecoder2D::G2D_fillRect,
&GCommandDecoder2D::G2D_fillText,
&GCommandDecoder2D::G2D_getImageData,
&GCommandDecoder2D::G2D_getLineDash,
&GCommandDecoder2D::G2D_lineTo,
&GCommandDecoder2D::G2D_measureText,
&GCommandDecoder2D::G2D_moveTo,
&GCommandDecoder2D::G2D_putImageData_3,
&GCommandDecoder2D::G2D_putImageData_7,
&GCommandDecoder2D::G2D_quadraticCurveTo,
&GCommandDecoder2D::G2D_rect,
&GCommandDecoder2D::G2D_restore,
&GCommandDecoder2D::G2D_rotate,
&GCommandDecoder2D::G2D_save,
&GCommandDecoder2D::G2D_scale,
&GCommandDecoder2D::G2D_setLineDash,
&GCommandDecoder2D::G2D_setTransform,
&GCommandDecoder2D::G2D_storke,
&GCommandDecoder2D::G2D_strokeRect,
&GCommandDecoder2D::G2D_strokeText,
&GCommandDecoder2D::G2D_transform,
&GCommandDecoder2D::G2D_translate,
&GCommandDecoder2D::G2D_setFillStyle_string,
&GCommandDecoder2D::G2D_setFillStyle_object,
&GCommandDecoder2D::G2D_setStrokeStyle_string,
&GCommandDecoder2D::G2D_setStrokeStyle_object,
&GCommandDecoder2D::G2D_setShadowColor,
&GCommandDecoder2D::G2D_setShadowBlur,
&GCommandDecoder2D::G2D_setShadowOffsetX,
&GCommandDecoder2D::G2D_setShadowOffsetY,
&GCommandDecoder2D::G2D_setLineCap,
&GCommandDecoder2D::G2D_setLineJoin,
&GCommandDecoder2D::G2D_setLineWidth,
&GCommandDecoder2D::G2D_setMiterLimit,
&GCommandDecoder2D::G2D_setLineDashOffset,
&GCommandDecoder2D::G2D_setFont,
&GCommandDecoder2D::G2D_setTextAlign,
&GCommandDecoder2D::G2D_setTextBaseline,
&GCommandDecoder2D::G2D_setGlobalAlpha,
&GCommandDecoder2D::G2D_setGlobalCompositeOperation
};
uint32_t *v;
while ( (v = buffer.parseValue<uint32_t>()) != nullptr )
{
uint32_t funcId = *v;
if( funcId <= 0 || funcId >= G2D_FUNC_COUNT )
{
LOG_E("[Error] Command buffer with wrong Context2D API ID:%d", funcId);
return false;
}
GCommand2DFunc func = mContext2DFuncs[funcId];
if( !func )
{
LOG_E("[Error] Can't find Context2D API ID::%d", funcId);
return false;
}
if( !mRenderContext2D )
{
LOG_E("[Error] mRenderContext2D is NULL!");
return false;
}
// LOG_D("==========API ID:[%d-%s]==========", funcId, WEBGL_API(funcId) );
func(mRenderContext2D, buffer, res);
if( res.hasResult && IsSyncCommand(funcId) )
{
return true;
}
}
return true;
}
void GCommandDecoder2D::G2D_arc(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[5];
bool ret = buffer.parseArray<float>(mFv, 5);
if( !ret ) return;
uint32_t mIv[1];
ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
context->mCanvas2D->Arc(mFv[0], mFv[1], mFv[2], mFv[3], mFv[4], mIv[0]);
LOG_D("[context2d::exec] arc(%f,%f,%f,%f,%f,%d)", mFv[0], mFv[1], mFv[2], mFv[3], mFv[4], mIv[0]);
}
void GCommandDecoder2D::G2D_arcTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[5];
bool ret = buffer.parseArray<float>(mFv, 5);
if( !ret ) return;
context->mCanvas2D->ArcTo(mFv[0], mFv[1], mFv[2], mFv[3], mFv[4]);
LOG_D("[context2d::exec] arcTo(%f,%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3], mFv[4]);
}
void GCommandDecoder2D::G2D_beginPath(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
context->mCanvas2D->BeginPath();
LOG_D("[context2d::exec] beginPath()");
}
void GCommandDecoder2D::G2D_bezierCurveTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[6];
bool ret = buffer.parseArray<float>(mFv, 6);
if( !ret ) return;
context->mCanvas2D->BezierCurveTo(mFv[0], mFv[1], mFv[2], mFv[3], mFv[4], mFv[5]);
LOG_D("[context2d::exec] bezierCurveTo(%f,%f,%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3], mFv[4], mFv[5]);
}
void GCommandDecoder2D::G2D_clearRect(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[4];
bool ret = buffer.parseArray<float>(mFv, 4);
if( !ret ) return;
context->mCanvas2D->ClearRect(mFv[0], mFv[1], mFv[2], mFv[3]);
LOG_D("[context2d::exec] clearRect(%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3]);
}
void GCommandDecoder2D::G2D_clip(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
context->mCanvas2D->Clip(GFillRule(mIv[0]));
LOG_D("[context2d::exec] clip(%d)", mIv[0]);
}
void GCommandDecoder2D::G2D_closePath(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
context->mCanvas2D->ClosePath();
LOG_D("[context2d::exec] closePath()");
}
void GCommandDecoder2D::G2D_createImageData_size(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
}
void GCommandDecoder2D::G2D_createImageData_data(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
}
void GCommandDecoder2D::G2D_createLinearGradient(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
}
void GCommandDecoder2D::G2D_createPattern(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
}
void GCommandDecoder2D::G2D_createRadialGradient(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
}
void GCommandDecoder2D::G2D_drawImage_3(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint64_t *uID = buffer.parseValue<uint64_t>();
if( !uID ) return;
float v[2];
bool ret = buffer.parseArray<float>(v, 2);
if( !ret ) return;
//fetch pixels
JSBindingPixels gPixels;
context->FetchPixels(*uID, 0, &gPixels);
if( gPixels.textureId > 0 ) //image/canvas
{
float sx = 0, sy = 0;
float sw = gPixels.width, sh = gPixels.height;
float dw = sw, dh = sh;
context->mCanvas2D->DrawImage(gPixels.textureId, gPixels.width, gPixels.height,
sx, sy, sw, sh, v[0], v[1], dw, dh);
LOG_D("[context2d::exec] DrawImage3(%d,%d,%d,%f,%f,%f,%f,%f,%f,%f,%f)",
gPixels.textureId, gPixels.width, gPixels.height,
sx, sy, sw, sh, v[0], v[1], dw, dh);
}
}
void GCommandDecoder2D::G2D_drawImage_5(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint64_t *uID = buffer.parseValue<uint64_t>();
if( !uID ) return;
float v[4];
bool ret = buffer.parseArray<float>(v, 4);
if( !ret ) return;
//fetch pixels
JSBindingPixels gPixels;
context->FetchPixels(*uID, 0, &gPixels);
if( gPixels.textureId > 0 ) //image/canvas
{
float sx = 0, sy = 0;
float sw = gPixels.width, sh = gPixels.height;
context->mCanvas2D->DrawImage(gPixels.textureId, gPixels.width, gPixels.height,
sx, sy, sw, sh, v[0], v[1], v[2], v[3]);
LOG_D("[context2d::exec] DrawImage5(%d,%d,%d,%f,%f,%f,%f,%f,%f,%f,%f)",
gPixels.textureId, gPixels.width, gPixels.height,
sx, sy, sw, sh, v[0], v[1], v[2], v[3]);
}
}
void GCommandDecoder2D::G2D_drawImage_9(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint64_t *uID = buffer.parseValue<uint64_t>();
if( !uID ) return;
float v[8];
bool ret = buffer.parseArray<float>(v, 8);
if( !ret ) return;
//fetch pixels
JSBindingPixels gPixels;
context->FetchPixels(*uID, 0, &gPixels);
if( gPixels.textureId > 0 ) //image/canvas
{
context->mCanvas2D->DrawImage(gPixels.textureId, gPixels.width, gPixels.height,
v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
LOG_D("[context2d::exec] DrawImage9(%d,%d,%d,%f,%f,%f,%f,%f,%f,%f,%f)",
gPixels.textureId, gPixels.width, gPixels.height,
v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
}
}
void GCommandDecoder2D::G2D_fill(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
context->mCanvas2D->Fill(GFillRule(mIv[0]));
LOG_D("[context2d::exec] fill(%d)", mIv[0]);
}
void GCommandDecoder2D::G2D_fillRect(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[4];
bool ret = buffer.parseArray<float>(mFv, 4);
if( !ret ) return;
context->mCanvas2D->FillRect(mFv[0], mFv[1], mFv[2], mFv[3]);
LOG_D("[context2d::exec] fillRect(%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3]);
}
void GCommandDecoder2D::G2D_fillText(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
size_t size = mIv[0];
if( size > 0 )
{
char16_t *u16Char = (char16_t*)buffer.parseBufferAlign(size);
std::string u8Str = U16StrToU8Str(u16Char);
float mFv[3];
ret = buffer.parseArray<float>(mFv, 3);
if( !ret ) return;
if( mFv[2] < 0 )
{
context->mCanvas2D->DrawText(u8Str.c_str(), mFv[0], mFv[1]);
LOG_D("[context2d::exec] fillText(%s,%f,%f)", u8Str.c_str(), mFv[0], mFv[1]);
}
else
{
context->mCanvas2D->DrawText(u8Str.c_str(), mFv[0], mFv[1], mFv[2]);
LOG_D("[context2d::exec] fillText(%s,%f,%f,%f)", u8Str.c_str(), mFv[0], mFv[1], mFv[2]);
}
}
}
void GCommandDecoder2D::G2D_getImageData(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
}
void GCommandDecoder2D::G2D_getLineDash(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
}
void GCommandDecoder2D::G2D_lineTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[2];
bool ret = buffer.parseArray<float>(mFv, 2);
if( !ret ) return;
context->mCanvas2D->LineTo(mFv[0], mFv[1]);
LOG_D("[context2d::exec] lineTo(%f,%f)", mFv[0], mFv[1]);
}
void GCommandDecoder2D::G2D_measureText(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
size_t size = mIv[0];
if( size > 0 )
{
char16_t *u16Char = (char16_t*)buffer.parseBufferAlign(size);
std::string u8Str = U16StrToU8Str(u16Char);
float width = context->mCanvas2D->MeasureTextWidth(u8Str.c_str());
res.hasResult = true;
res.type = GResType_MeasureText;
res.floatValue = width;
LOG_D("[context2d::exec] measureText(%s)=%f", u8Str.c_str(), width);
}
}
void GCommandDecoder2D::G2D_moveTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[2];
bool ret = buffer.parseArray<float>(mFv, 2);
if( !ret ) return;
context->mCanvas2D->MoveTo(mFv[0], mFv[1]);
LOG_D("[context2d::exec] moveTo(%f,%f)", mFv[0], mFv[1]);
}
void GCommandDecoder2D::G2D_putImageData_3(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
// self.context->mCanvas2D->DrawImage(texture.textureId, texture.width, texture.height, sx, sy, sw, sh, dx, dy, dw, dh, false);
}
void GCommandDecoder2D::G2D_putImageData_7(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
//TODO
// self.context->mCanvas2D->DrawImage(texture.textureId, texture.width, texture.height, sx, sy, sw, sh, dx, dy, dw, dh, false);
}
void GCommandDecoder2D::G2D_quadraticCurveTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[4];
bool ret = buffer.parseArray<float>(mFv, 4);
if( !ret ) return;
context->mCanvas2D->QuadraticCurveTo(mFv[0], mFv[1], mFv[2], mFv[3]);
LOG_D("[context2d::exec] quadraticCurveTo(%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3]);
}
void GCommandDecoder2D::G2D_rect(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[4];
bool ret = buffer.parseArray<float>(mFv, 4);
if( !ret ) return;
context->mCanvas2D->Rect(mFv[0], mFv[1], mFv[2], mFv[3]);
LOG_D("[context2d::exec] rect(%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3]);
}
void GCommandDecoder2D::G2D_restore(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
context->mCanvas2D->Restore();
LOG_D("[context2d::exec] restore()");
}
void GCommandDecoder2D::G2D_rotate(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[1];
bool ret = buffer.parseArray<float>(mFv, 1);
if( !ret ) return;
context->mCanvas2D->Rotate(mFv[0]);
LOG_D("[context2d::exec] rotate(%d)", mFv[0]);
}
void GCommandDecoder2D::G2D_save(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
context->mCanvas2D->Save();
LOG_D("[context2d::exec] save()");
}
void GCommandDecoder2D::G2D_scale(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[2];
bool ret = buffer.parseArray<float>(mFv, 2);
if( !ret ) return;
context->mCanvas2D->Scale(mFv[0], mFv[1]);
LOG_D("[context2d::exec] scale(%f,%f)", mFv[0], mFv[1]);
}
void GCommandDecoder2D::G2D_setLineDash(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
size_t size = mIv[0];
if( size > 0 )
{
float* mFv = (float*)(buffer.parseBuffer(size*4));
if( mFv )
{
std::vector<float>lineDash;
for (int i=0; i<size; ++i) {
lineDash.push_back(*(mFv+i));
}
context->mCanvas2D->SetLineDash(lineDash);
}
}
}
void GCommandDecoder2D::G2D_setTransform(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[6];
bool ret = buffer.parseArray<float>(mFv, 6);
if( !ret ) return;
context->mCanvas2D->SetTransform(mFv[0], mFv[1], mFv[2], mFv[3], mFv[4], mFv[5]);
LOG_D("[context2d::exec] setTransform(%f,%f,%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3], mFv[4], mFv[5]);
}
void GCommandDecoder2D::G2D_storke(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
context->mCanvas2D->Stroke();
LOG_D("[context2d::exec] stroke()");
}
void GCommandDecoder2D::G2D_strokeRect(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[4];
bool ret = buffer.parseArray<float>(mFv, 4);
if( !ret ) return;
context->mCanvas2D->StrokeRect(mFv[0], mFv[1], mFv[2], mFv[3]);
LOG_D("[context2d::exec] strokeRect(%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3]);
}
void GCommandDecoder2D::G2D_strokeText(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
size_t size = mIv[0];
if( size > 0 )
{
char16_t *u16Char = (char16_t*)buffer.parseBufferAlign(size);
std::string u8Str = U16StrToU8Str(u16Char);
float mFv[3];
ret = buffer.parseArray<float>(mFv, 3);
if( !ret ) return;
if( mFv[2] < 0 )
{
context->mCanvas2D->StrokeText(u8Str.c_str(), mFv[0], mFv[1]);
LOG_D("[context2d::exec] strokeText(%s,%f,%f)", u8Str.c_str(), mFv[0], mFv[1]);
}
else
{
context->mCanvas2D->StrokeText(u8Str.c_str(), mFv[0], mFv[1], mFv[2]);
LOG_D("[context2d::exec] strokeText(%s,%f,%f,%f)", u8Str.c_str(), mFv[0], mFv[1], mFv[2]);
}
}
}
void GCommandDecoder2D::G2D_transform(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[6];
bool ret = buffer.parseArray<float>(mFv, 6);
if( !ret ) return;
context->mCanvas2D->Transfrom(mFv[0], mFv[1], mFv[2], mFv[3], mFv[4], mFv[5]);
LOG_D("[context2d::exec] transform(%f,%f,%f,%f,%f,%f)", mFv[0], mFv[1], mFv[2], mFv[3], mFv[4], mFv[5]);
}
void GCommandDecoder2D::G2D_translate(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[2];
bool ret = buffer.parseArray<float>(mFv, 2);
if( !ret ) return;
context->mCanvas2D->Translate(mFv[0], mFv[1]);
LOG_D("[context2d::exec] translate(%f,%f)", mFv[0], mFv[1]);
}
//////////////////////////////
/// Set Property
//////////////////////////////
void GCommandDecoder2D::G2D_setFillStyle_string(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
size_t size = mIv[0];
if( size > 0 )
{
char16_t *u16Char = (char16_t*)buffer.parseBufferAlign(size);
if( !u16Char ) return;
std::string u8Str = U16StrToU8Str(u16Char);
context->mCanvas2D->SetFillStyle(u8Str.c_str());
LOG_D("[context2d::exec] setFillStyle(%s)", u8Str.c_str());
}
}
void GCommandDecoder2D::G2D_setFillStyle_object(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint64_t *uID = buffer.parseValue<uint64_t>();
if( !uID ) return;
context->SetFillStrokeStyle(*uID, false);
}
void GCommandDecoder2D::G2D_setStrokeStyle_string(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
size_t size = mIv[0];
if( size > 0 )
{
char16_t *u16Char = (char16_t*)buffer.parseBufferAlign(size);
if( !u16Char ) return;
std::string u8Str = U16StrToU8Str(u16Char);
context->mCanvas2D->SetStrokeStyle(u8Str.c_str());
LOG_D("[context2d::exec] setStrokeStyle(%s)", u8Str.c_str());
}
}
void GCommandDecoder2D::G2D_setStrokeStyle_object(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint64_t *uID = buffer.parseValue<uint64_t>();
if( !uID ) return;
context->SetFillStrokeStyle(*uID, true);
}
void GCommandDecoder2D::G2D_setShadowColor(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
size_t size = mIv[0];
if( size > 0 )
{
char16_t *u16Char = (char16_t*)buffer.parseBufferAlign(size);
if( !u16Char ) return;
std::string u8Str = U16StrToU8Str(u16Char);
context->mCanvas2D->SetShadowColor(u8Str.c_str());
LOG_D("[context2d::exec] setShadowColor(%s)", u8Str.c_str());
}
}
void GCommandDecoder2D::G2D_setShadowBlur(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[1];
bool ret = buffer.parseArray<float>(mFv, 1);
if( !ret ) return;
context->mCanvas2D->SetShadowBlur(mFv[0]);
LOG_D("[context2d::exec] setShadowBlur(%f)", mFv[0]);
}
void GCommandDecoder2D::G2D_setShadowOffsetX(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[1];
bool ret = buffer.parseArray<float>(mFv, 1);
if( !ret ) return;
context->mCanvas2D->SetShadowOffsetX(mFv[0]);
LOG_D("[context2d::exec] setShadowOffsetX(%f)", mFv[0]);
}
void GCommandDecoder2D::G2D_setShadowOffsetY(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[1];
bool ret = buffer.parseArray<float>(mFv, 1);
if( !ret ) return;
context->mCanvas2D->SetShadowOffsetY(mFv[0]);
LOG_D("[context2d::exec] setShadowOffsetY(%f)", mFv[0]);
}
void GCommandDecoder2D::G2D_setLineCap(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
context->mCanvas2D->SetLineCap((GLineCap)mIv[0]);
LOG_D("[context2d::exec] setLineCap(%d)", mIv[0]);
}
void GCommandDecoder2D::G2D_setLineJoin(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
context->mCanvas2D->SetLineJoin((GLineJoin)mIv[0]);
LOG_D("[context2d::exec] setLineJoin(%d)", mIv[0]);
}
void GCommandDecoder2D::G2D_setLineWidth(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[1];
bool ret = buffer.parseArray<float>(mFv, 1);
if( !ret ) return;
context->mCanvas2D->SetLineWidth(mFv[0]);
LOG_D("[context2d::exec] setLineWidth(%f)", mFv[0]);
}
void GCommandDecoder2D::G2D_setMiterLimit(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[1];
bool ret = buffer.parseArray<float>(mFv, 1);
if( !ret ) return;
context->mCanvas2D->SetMiterLimit(mFv[0]);
LOG_D("[context2d::exec] setMiterLimit(%f)", mFv[0]);
}
void GCommandDecoder2D::G2D_setLineDashOffset(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[1];
bool ret = buffer.parseArray<float>(mFv, 1);
if( !ret ) return;
context->mCanvas2D->SetLineDashOffset(mFv[0]);
LOG_D("[context2d::exec] setLineDashOffset(%f)", mFv[0]);
}
void GCommandDecoder2D::G2D_setFont(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
size_t size = mIv[0];
if( size > 0 )
{
char16_t *u16Char = (char16_t*)buffer.parseBufferAlign(size);
if( !u16Char ) return;
std::string u8Str = U16StrToU8Str(u16Char);
context->mCanvas2D->SetFont(u8Str.c_str());
LOG_D("[context2d::exec] setFont(%s)", u8Str.c_str());
}
}
void GCommandDecoder2D::G2D_setTextAlign(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
context->mCanvas2D->SetTextAlign((GTextAlign)mIv[0]);
LOG_D("[context2d::exec] setTextAlign(%d)", mIv[0]);
}
void GCommandDecoder2D::G2D_setTextBaseline(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
context->mCanvas2D->SetTextBaseline((GTextBaseline)mIv[0]);
LOG_D("[context2d::exec] setTextBaseline(%d)", mIv[0]);
}
void GCommandDecoder2D::G2D_setGlobalAlpha(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
float mFv[1];
bool ret = buffer.parseArray<float>(mFv, 1);
if( !ret ) return;
context->mCanvas2D->SetGlobalAlpha(mFv[0]);
LOG_D("[context2d::exec] setGlobalAlpha(%f)", mFv[0]);
}
void GCommandDecoder2D::G2D_setGlobalCompositeOperation(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res)
{
uint32_t mIv[1];
bool ret = buffer.parseArray<uint32_t>(mIv, 1);
if( !ret ) return;
context->mCanvas2D->SetGlobalCompositeOperation(mIv[0]);
LOG_D("[context2d::exec] setGlobalCompositeOperation(%d)", mIv[0]);
}
} // namespace gcanvas
#endif

View File

@ -0,0 +1,174 @@
/**
* Created by G-Canvas Open Source Team.
* Copyright (c) 2017, Alibaba, Inc. All rights reserved.
*
* This source code is licensed under the Apache Licence 2.0.
* For the full copyright and license information, please view
* the LICENSE file in the root directory of this source tree.
*/
#ifdef COMMANDBUFFER_2D
#ifndef GCANVAS_GCOMMANDDECODER2D_H
#define GCANVAS_GCOMMANDDECODER2D_H
#include <string>
#include <unordered_set>
#include "../commandbuffer/GCommandDecoder.hpp"
#include "GContext2DRenderContext.hpp"
namespace gcanvas
{
class GCommandDecoder2D : public GCommandDecoder
{
enum G2D_FUNC_ID
{
G2D_FUNC_arc = 1,
G2D_FUNC_arcTo,
G2D_FUNC_beginPath,
G2D_FUNC_bezierCurveTo,
G2D_FUNC_clearRect,
G2D_FUNC_clip,
G2D_FUNC_closePath,
G2D_FUNC_createImageData_size,
G2D_FUNC_createImageData_data,
G2D_FUNC_createLinearGradient = 10,
G2D_FUNC_createPattern,
G2D_FUNC_createRadialGradient,
G2D_FUNC_drawImage_3,
G2D_FUNC_drawImage_6,
G2D_FUNC_drawImage_9,
G2D_FUNC_fill,
G2D_FUNC_fillRect,
G2D_FUNC_fillText,
G2D_FUNC_getImageData,
G2D_FUNC_getLineDash = 20,
G2D_FUNC_lineTo,
G2D_FUNC_measureText,
G2D_FUNC_moveTo,
G2D_FUNC_putImageData_3,
G2D_FUNC_putImageData_7,
G2D_FUNC_quadraticCurveTo,
G2D_FUNC_rect,
G2D_FUNC_restore,
G2D_FUNC_rotate,
G2D_FUNC_save = 30,
G2D_FUNC_scale,
G2D_FUNC_setLineDash,
G2D_FUNC_setTransform,
G2D_FUNC_storke,
G2D_FUNC_strokeRect,
G2D_FUNC_strokeText,
G2D_FUNC_transform,
G2D_FUNC_translate,
//property
G2D_FUNC_setFillStyle_string,
G2D_FUNC_setFillStyle_object = 40,
G2D_FUNC_setStrokeStyle_string,
G2D_FUNC_setStrokeStyle_object,
G2D_FUNC_setShadowColor,
G2D_FUNC_setShadowBlur,
G2D_FUNC_setShadowOffsetX,
G2D_FUNC_setShadowOffsetY,
G2D_FUNC_setLineCap,
G2D_FUNC_setLineJoin,
G2D_FUNC_setLineWidth,
G2D_FUNC_setMiterLimit = 50,
G2D_FUNC_setLineDashOffset,
G2D_FUNC_setFont,
G2D_FUNC_setTextAlign,
G2D_FUNC_setTextBaseline,
G2D_FUNC_setGlobalAlpha,
G2D_FUNC_setGlobalCompositeOperation,
//API数量
G2D_FUNC_COUNT,
};
public:
API_EXPORT GCommandDecoder2D(GContext2DRenderContext* renderCtx);
API_EXPORT ~GCommandDecoder2D();
virtual void InitCommands();
virtual bool IsSyncCommand(uint32_t cmdId){
auto iter = mContext2DSyncFuncSet.find(cmdId);
return iter != mContext2DSyncFuncSet.end();
}
API_EXPORT virtual bool Decode(GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_arc(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_arcTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_beginPath(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_bezierCurveTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_clearRect(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_clip(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_closePath(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_createImageData_size(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_createImageData_data(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_createLinearGradient(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_createPattern(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_createRadialGradient(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_drawImage_3(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_drawImage_5(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_drawImage_9(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_fill(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_fillRect(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_fillText(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_getImageData(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_getLineDash(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_lineTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_measureText(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_moveTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_putImageData_3(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_putImageData_7(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_quadraticCurveTo(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_rect(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_restore(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_rotate(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_save(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_scale(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setLineDash(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setTransform(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_storke(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_strokeRect(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_strokeText(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_transform(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_translate(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setFillStyle_string(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setFillStyle_object(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setStrokeStyle_string(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setStrokeStyle_object(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setShadowColor(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setShadowBlur(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setShadowOffsetX(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setShadowOffsetY(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setLineCap(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setLineJoin(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setLineWidth(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setMiterLimit(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setLineDashOffset(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setFont(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setTextAlign(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setTextBaseline(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setGlobalAlpha(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
static void G2D_setGlobalCompositeOperation(GContext2DRenderContext* context, GCommandBuffer& buffer, GDecodeRes& res);
protected:
std::unordered_set<unsigned int> mContext2DSyncFuncSet;
// GCanvasContext * mCanvasContext;
GContext2DRenderContext * mRenderContext2D;
// static float mFv[8]; //max float param num is 8
// static uint32_t mIv[4];
};
} //namespace gcanvas
#endif /* GCANVAS_GCOMMANDDECODERWEBGL_H */
#endif

View File

@ -0,0 +1,49 @@
/**
* Created by G-Canvas Open Source Team.
* Copyright (c) 2017, Alibaba, Inc. All rights reserved.
*
* This source code is licensed under the Apache Licence 2.0.
* For the full copyright and license information, please view
* the LICENSE file in the root directory of this source tree.
*/
#ifdef COMMANDBUFFER_2D
#include "GContext2DRenderContext.hpp"
#include <algorithm>
#include "../support/Log.h"
#include "GGL.h"
namespace gcanvas {
GContext2DRenderContext::GContext2DRenderContext(void* data, GCanvasContext* context, std::string contextId)
: mData(data), mCanvas2D(context), mContextId(contextId), mDrawCall(0),
mNeed_draw(false)
{
}
GContext2DRenderContext::~GContext2DRenderContext()
{
}
void GContext2DRenderContext::FetchPixels(uint64_t uid, int format, JSBindingPixels* pixels)
{
if (mFetchPixelsFunc)
{
mFetchPixelsFunc(mData, uid, pixels);
}
}
void GContext2DRenderContext::SetFillStrokeStyle(uint64_t uid, bool isStroke)
{
if (mSetFillStrokeStyleFunc)
{
mSetFillStrokeStyleFunc(mData, uid, isStroke);
}
}
} //namespace gcanvas
#endif

View File

@ -0,0 +1,62 @@
/**
* Created by G-Canvas Open Source Team.
* Copyright (c) 2017, Alibaba, Inc. All rights reserved.
*
* This source code is licensed under the Apache Licence 2.0.
* For the full copyright and license information, please view
* the LICENSE file in the root directory of this source tree.
*/
#ifdef COMMANDBUFFER_2D
#ifndef GCANVAS_GCONTEXT2DRENDERCONTEXT_H
#define GCANVAS_GCONTEXT2DRENDERCONTEXT_H
#include <stdio.h>
#include <string>
#include <unordered_set>
#include <memory>
#include <unordered_map>
#include <set>
#include <vector>
#include "../export.h"
#include "../gcanvas/GCanvas2dContext.h"
#include "GGL.h"
#include "GCommandTypes.hpp"
namespace gcanvas
{
//Set sytle with instance with instanceID
using SetFillStrokeStyleFunc = std::function< void (void*, uint64_t, bool) >;
class GContext2DRenderContext
{
public:
API_EXPORT GContext2DRenderContext(void* data, GCanvasContext* context, std::string contextId);
API_EXPORT ~GContext2DRenderContext();
void FetchPixels(uint64_t uid, int format, JSBindingPixels* pixels);
void SetFillStrokeStyle(uint64_t uid, bool isStroke);
FetchPixelsFunc mFetchPixelsFunc;
SetFillStrokeStyleFunc mSetFillStrokeStyleFunc;
long mDrawCall;
std::atomic_bool mNeed_draw;
GCanvasContext* mCanvas2D;
protected:
void* mData; //RTContext2DBatchRender
std::string mContextId;
};
} //namespace gcanvas
#endif /* GCANVAS_GCONTEXT2DRENDERCONTEXT_H */
#endif

View File

@ -14,115 +14,11 @@
#include <memory>
#include <functional>
#include "GCommandBuffer.hpp"
#include "GCommandTypes.hpp"
namespace gcanvas
{
enum GResType
{
GResType_NONE = 0,
GResType_NULL,
GResType_Bool,
GResType_Int32,
GResType_UInt32,
GResType_UInt32_CreateBuffer,
GResType_UInt32_CreateTexture,
GResType_UInt32_CreateFrameBuffer,
GResType_UInt32_CreateShader,
GResType_UInt32_CreateProgram,
GResType_UInt32_CreateRenderBuffer,
GResType_UInt32_CreateVertexArray,//extension
GResType_Float,
GResType_BoolPtr,
GResType_CharPtr,
GResType_Int32Ptr,
GResType_UInt32Ptr,
GResType_FloatPtr,
GResType_CharPtr_GetExtention,
GResType_CharPtr_GetSupportedExtention,
GResType_GetContextAttributes
};
/**
`GDecodeRes` struct save the value of each batch render while has result
*/
struct GDecodeRes
{
bool hasResult;
GResType type;
//result is a typed value
union
{
uint8_t boolValue;
int32_t intValue;
uint32_t uintValue;
float floatValue;
};
//multi return value, while point value not nullptr, delete it before use
union
{
char * charPtrValue;
int32_t * intPtrValue;
uint32_t * uintPtrValue;
float * floatPtrValue;
};
//size of element
size_t length;
//size of byte size
size_t byteSize;
size_t maxSize;
GDecodeRes()
{
maxSize = 2048;
hasResult = false;
type = GResType_NONE;
uintValue = 0;
charPtrValue = new char[maxSize];
}
~GDecodeRes()
{
if( charPtrValue )
{
delete charPtrValue;
charPtrValue = nullptr;
}
}
inline void checkSize(size_t size)
{
if( size <= maxSize ) return;
maxSize += size*2;
char * newCharPtrValue = new char[maxSize];
if( newCharPtrValue ){
delete charPtrValue;
charPtrValue = newCharPtrValue;
}
}
//reset before use
inline void reset()
{
hasResult = false;
type = GResType_NONE;
uintValue = 0;
length = byteSize = 0;
}
};
//define WebGL API function
//using GCommandFunc = std::function< void(GCommandBuffer& buffer, GDecodeRes& res ) >;
typedef void (*GCommandFuncPtr)(GCommandBuffer& , GDecodeRes& );
//convert utf16 string to utf8 string
std::string U16StrToU8Str( char16_t* u16char );
class GCommandDecoder
{
public:
@ -138,7 +34,7 @@ public:
}
virtual void InitCommands() = 0;
virtual bool Decode(GCommandBuffer& buffer, GDecodeRes& res) = 0;
// virtual bool Decode(GCommandBuffer& buffer, GDecodeRes& res) = 0;
virtual bool IsSyncCommand(uint32_t commandId) = 0;
protected:

View File

@ -0,0 +1,27 @@
/**
* Created by G-Canvas Open Source Team.
* Copyright (c) 2017, Alibaba, Inc. All rights reserved.
*
* This source code is licensed under the Apache Licence 2.0.
* For the full copyright and license information, please view
* the LICENSE file in the root directory of this source tree.
*/
#include "GCommandTypes.hpp"
namespace gcanvas
{
JSBindingPixels::JSBindingPixels():
textureId(0), width(0), height(0), pixels(nullptr)
{
}
JSBindingPixels::~JSBindingPixels()
{
}
}

View File

@ -0,0 +1,158 @@
/**
* Created by G-Canvas Open Source Team.
* Copyright (c) 2017, Alibaba, Inc. All rights reserved.
*
* This source code is licensed under the Apache Licence 2.0.
* For the full copyright and license information, please view
* the LICENSE file in the root directory of this source tree.
*/
#ifndef GCANVAS_GCOMMANDTYPES_H
#define GCANVAS_GCOMMANDTYPES_H
#include <stdio.h>
#include <memory>
#include <functional>
#include "../export.h"
namespace gcanvas
{
class GCommandBuffer;
class JSBindingPixels
{
public:
API_EXPORT JSBindingPixels();
API_EXPORT ~JSBindingPixels();
JSBindingPixels(JSBindingPixels &&v)
{
textureId = v.textureId;
pixels = v.pixels;
width = v.width;
height = v.height;
v.textureId = 0;
v.pixels = nullptr;
v.width = 0;
v.height = 0;
}
uint32_t textureId;
uint8_t* pixels;
short width;
short height;
};
//Fectch pixels form JSBinding instance with instanceID
using FetchPixelsFunc = std::function< void (void*obj, uint64_t, JSBindingPixels*) >;
enum GResType
{
GResType_NONE = 0,
GResType_NULL,
GResType_Bool,
GResType_Int32,
GResType_UInt32,
GResType_UInt32_CreateBuffer,
GResType_UInt32_CreateTexture,
GResType_UInt32_CreateFrameBuffer,
GResType_UInt32_CreateShader,
GResType_UInt32_CreateProgram,
GResType_UInt32_CreateRenderBuffer,
GResType_UInt32_CreateVertexArray,//extension
GResType_Float,
GResType_BoolPtr,
GResType_CharPtr,
GResType_Int32Ptr,
GResType_UInt32Ptr,
GResType_FloatPtr,
GResType_CharPtr_GetExtention,
GResType_CharPtr_GetSupportedExtention,
GResType_GetContextAttributes,
//2d
GResType_MeasureText,
};
/**
`GDecodeRes` struct save the value of each batch render while has result
*/
struct GDecodeRes
{
bool hasResult;
GResType type;
//result is a typed value
union
{
uint8_t boolValue;
int32_t intValue;
uint32_t uintValue;
float floatValue;
};
//multi return value, while point value not nullptr, delete it before use
union
{
char * charPtrValue;
int32_t * intPtrValue;
uint32_t * uintPtrValue;
float * floatPtrValue;
};
//size of element
size_t length;
//size of byte size
size_t byteSize;
size_t maxSize;
GDecodeRes()
{
maxSize = 2048;
hasResult = false;
type = GResType_NONE;
uintValue = 0;
charPtrValue = new char[maxSize];
}
~GDecodeRes()
{
if( charPtrValue )
{
delete charPtrValue;
charPtrValue = nullptr;
}
}
inline void checkSize(size_t size)
{
if( size <= maxSize ) return;
maxSize += size*2;
char * newCharPtrValue = new char[maxSize];
if( newCharPtrValue ){
delete charPtrValue;
charPtrValue = newCharPtrValue;
}
}
//reset before use
inline void reset()
{
hasResult = false;
type = GResType_NONE;
uintValue = 0;
length = byteSize = 0;
}
};
//convert utf16 string to utf8 string
std::string U16StrToU8Str( char16_t* u16char );
}
#endif /* GCANVAS_GCOMMANDTYPES_H */

View File

@ -7,11 +7,12 @@
* the LICENSE file in the root directory of this source tree.
*/
#include "GCanvas2dContext.h"
#include "GShaderManager.h"
#include "../GCanvas.hpp"
#include "GL/GLUtil.h"
#include <stdio.h>
#include <assert.h>
#define SIZE_EPSILON 1.f
@ -32,6 +33,7 @@ GBlendOperationFuncs GCompositeOperationFuncs(int index)
{GL_ONE, GL_ONE}, // 8 lighter
{GL_ONE, GL_ZERO}, // 9 copy
{GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, // 10 xor
{GL_ZERO, GL_ZERO},// 11 clear
};
if (index < COMPOSITE_OP_SOURCE_OVER || index >= COMPOSITE_OP_NONE)
@ -1227,7 +1229,7 @@ void GCanvasContext::DrawFBOToScreen(GFrameBufferObject &fbo, float x, float y,
PushRectangle4TextureArea(x, y, w, h, 0, 0,
static_cast<float>(fbo.ExpectedWidth()) / fbo.Width(),
static_cast<float>(fbo.ExpectedHeight()) / fbo.Height(),
color, GTransformIdentity, false);
color, GTransformIdentity, true);
}
void GCanvasContext::DoDrawBlur(const GRectf &rect, float blur, std::function<void()> draw,
@ -1620,10 +1622,19 @@ void GCanvasContext::UsePatternRenderPipeline(bool isStroke)
SendVertexBufferToGPU();
mCurrentState->mShader = newShader;
mCurrentState->mShader->Bind();
}
else if (newShader != nullptr)
{
GFillStyle *style = isStroke ? mCurrentState->mStrokeStyle : mCurrentState->mFillStyle;
if (style != mCurrentState->mCurrentFillStyle && !style->IsSameAs(mCurrentState->mCurrentFillStyle))
{
SendVertexBufferToGPU();
}
}
//Pattern
GFillStyle *style = isStroke ? mCurrentState->mStrokeStyle : mCurrentState->mFillStyle;
mCurrentState->mCurrentFillStyle = style;
if (style != nullptr && style->IsPattern() && mCurrentState->mShader)
{
FillStylePattern *pattern = (FillStylePattern *)(style);
@ -1653,9 +1664,18 @@ void GCanvasContext::UseLinearGradientPipeline(bool isStroke)
SendVertexBufferToGPU();
mCurrentState->mShader = newShader;
mCurrentState->mShader->Bind();
}
else if (newShader != nullptr)
{
GFillStyle *style = isStroke ? mCurrentState->mStrokeStyle : mCurrentState->mFillStyle;
if (style != mCurrentState->mCurrentFillStyle && !style->IsSameAs(mCurrentState->mCurrentFillStyle))
{
SendVertexBufferToGPU();
}
}
GFillStyle *style = isStroke ? mCurrentState->mStrokeStyle : mCurrentState->mFillStyle;
mCurrentState->mCurrentFillStyle = style;
if (style != nullptr && style->IsLinearGradient() && mCurrentState->mShader)
{
FillStyleLinearGradient *grad = (FillStyleLinearGradient *)(style);
@ -1684,10 +1704,19 @@ void GCanvasContext::UseRadialGradientPipeline(bool isStroke)
SendVertexBufferToGPU();
mCurrentState->mShader = newShader;
mCurrentState->mShader->Bind();
}
else if (newShader != nullptr)
{
GFillStyle *style = isStroke ? mCurrentState->mStrokeStyle : mCurrentState->mFillStyle;
if (style != mCurrentState->mCurrentFillStyle && !style->IsSameAs(mCurrentState->mCurrentFillStyle))
{
SendVertexBufferToGPU();
}
}
//Radial Gradinet
GFillStyle *style = isStroke ? mCurrentState->mStrokeStyle : mCurrentState->mFillStyle;
mCurrentState->mCurrentFillStyle = style;
if (style != nullptr && style->IsRadialGradient() && mCurrentState->mShader)
{
FillStyleRadialGradient *grad = (FillStyleRadialGradient *)(style);
@ -1784,21 +1813,35 @@ void GCanvasContext::SetFont(const char *font)
{
return;
}
delete mCurrentState->mFont;
}
mCurrentState->mFont = new GFontStyle(font, mDevicePixelRatio);
GFontStyle* fontStyle = GFontStyle::Parse(font, mDevicePixelRatio);
if (fontStyle != nullptr)
{
if (mCurrentState->mFont != nullptr)
{
delete mCurrentState->mFont;
}
mCurrentState->mFont = fontStyle;
}
}
//shadow
void GCanvasContext::SetShadowColor(const char *str)
{
GColorRGBA color = StrValueToColorRGBA(str);
mCurrentState->mShadowColor = color;
void GCanvasContext::SetShadowColor(const char *str) {
GColorRGBA color;
bool flag = StrValueToColorRGBA(str, color);
if (flag)
{
mCurrentState->mShadowColor = color;
}
}
void GCanvasContext::SetShadowBlur(float blur)
{
mCurrentState->mShadowBlur = blur;
void GCanvasContext::SetShadowBlur(float blur) {
if (blur >= 0)
{
mCurrentState->mShadowBlur = blur;
}
}
void GCanvasContext::SetShadowOffsetX(float x)
@ -1819,54 +1862,12 @@ void GCanvasContext::SetFillStyle(const char *str)
return;
}
GColorRGBA color = StrValueToColorRGBA(str);
SetFillStyle(color);
// mock();
}
void GCanvasContext::mock()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glViewport(0, 0, mWidth, mHeight);
glClear(GL_COLOR_BUFFER_BIT);
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,
-1.0f,
0.0f,
1.0f,
-1.0f,
0.0f,
0.0f,
1.0f,
0.0f,
};
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void *)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
// glDisableVertexAttribArray(0);
// glFlush();
GColorRGBA color;
bool flag = StrValueToColorRGBA(str, color);
if (flag)
{
SetFillStyle(color);
}
}
void GCanvasContext::SetFillStyle(GColorRGBA c)
@ -1876,9 +1877,7 @@ void GCanvasContext::SetFillStyle(GColorRGBA c)
delete mCurrentState->mFillStyle;
mCurrentState->mFillStyle = nullptr;
}
mCurrentState->mFillColor = c;
// UseDefaultRenderPipeline();
}
void GCanvasContext::SetStrokeStyle(const char *str)
@ -1898,12 +1897,7 @@ void GCanvasContext::SetStrokeStyle(const GColorRGBA &c)
delete mCurrentState->mStrokeStyle;
mCurrentState->mStrokeStyle = nullptr;
}
mCurrentState->mStrokeColor = c;
// UseDefaultRenderPipeline();
// if (mCurrentState->mShader != nullptr) {
// mCurrentState->mShader->SetHasTexture(0);
// }
}
void GCanvasContext::SetFillStylePattern(int textureId, int width, int height, const char *repeatMode,
@ -2594,24 +2588,21 @@ void GCanvasContext::DrawImage(int textureId, int textureWidth, int textureHeigh
GColorRGBA color = BlendWhiteColor(this);
SetTexture(textureId);
// if (NeedDrawShadow())
// {
// std::vector<GVertex> vec;
// PushRectangle(dx, dy, dw, dh, sx / textureWidth, sy / textureHeight, sw / textureWidth,
// sh / textureHeight, color, mCurrentState->mTransform, flipY, &vec);
if (NeedDrawShadow()) {
std::vector<GVertex> vec;
PushRectangle(dx, dy, dw, dh, sx / textureWidth, sy / textureHeight, sw / textureWidth,
sh / textureHeight, color, mCurrentState->mTransform, flipY, &vec);
// GRectf rect;
// GPath::GetRectCoverVertex(rect, vec);
// DrawShadow(rect, [&] {
// PushVertexs(vec);
// });
// PushVertexs(vec);
// }
// else
// {
PushRectangle(dx, dy, dw, dh, sx / textureWidth, sy / textureHeight, sw / textureWidth,
sh / textureHeight, color, mCurrentState->mTransform, flipY);
// }
GRectf rect;
GPath::GetRectCoverVertex(rect, vec);
DrawShadow(rect, [&] {
PushVertexs(vec);
});
PushVertexs(vec);
} else {
PushRectangle(dx, dy, dw, dh, sx / textureWidth, sy / textureHeight, sw / textureWidth,
sh / textureHeight, color, mCurrentState->mTransform, flipY);
}
}
void GCanvasContext::DoDrawImage(float w, float h, int TextureId, float sx,
@ -2634,16 +2625,11 @@ void GCanvasContext::DoDrawImage(float w, float h, int TextureId, float sx,
void GCanvasContext::GetImageData(int x, int y, int width, int height, uint8_t *pixels)
{
SendVertexBufferToGPU();
std::vector<int> rawPixel;
if (width < 0)
{
if (width < 0) {
x += width;
width = -width;
}
if (height < 0)
{
if (height < 0) {
y += height;
height = -height;
}
@ -2657,42 +2643,107 @@ void GCanvasContext::GetImageData(int x, int y, int width, int height, uint8_t *
int realWidth = width * sw;
int realHeight = height * sh;
rawPixel.resize(realWidth * realHeight);
uint8_t* rawPixel = new uint8_t[realWidth * realHeight * 4];
//read pixels
glReadPixels(realX, mHeight - (realY + realHeight), realWidth, realHeight, GL_RGBA,
GL_UNSIGNED_BYTE, &rawPixel[0]);
GL_UNSIGNED_BYTE, (void*)rawPixel);
GLenum glerror = glGetError();
if (glerror)
{
if (glerror) {
LOG_EXCEPTION(mHooks, mContextId, "glReadPixels_fail", "<function:%s, glGetError:%x>",
__FUNCTION__,
glerror);
}
// sample
gcanvas::PixelsSampler(realWidth, realHeight, &rawPixel[0], width, height,
reinterpret_cast<int *>(pixels));
if (realWidth != width || realHeight != height) {
gcanvas::PixelsSampler(realWidth, realHeight, (int*)rawPixel, width, height,
reinterpret_cast<int *>(pixels));
} else {
gcanvas::FlipYPixels(width, height, (int*)rawPixel, (int*)pixels);
}
#ifdef ANDROID
// for outside region, clear it with 0
int posX = 0;
int posY = 0;
int* ipixels = (int*)pixels;
if (x < 0 || y < 0 || x >= mWidth || y >= mHeight) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
posX = j + x;
posY = i + y;
if (posX < 0 || posY < 0 || posX >= mWidth || posY >= mHeight ) {
ipixels[i * width + j] = 0;
}
}
}
}
#endif
if (rawPixel != nullptr) {
delete[] rawPixel;
}
}
void GCanvasContext::PutImageData(const unsigned char *rgbaData, int tw,
int th, int x, int y, int sx, int sy,
int sw, int sh, bool is_src_flip_y)
{
void GCanvasContext::PutImageData(const unsigned char *rgbaData,
int tw, int th, int x, int y,
int dirtyX, int dirtyY, int dirtyW, int dirtyH, bool is_src_flip_y) {
PutImageDataFloat(rgbaData, tw, th, x, y, dirtyX, dirtyY, dirtyW, dirtyH, is_src_flip_y);
}
void GCanvasContext::PutImageDataFloat(const unsigned char *rgbaData,
int tw, int th, float x, float y,
float dirtyX, float dirtyY, float dirtyW, float dirtyH, bool is_src_flip_y) {
SendVertexBufferToGPU();
std::vector<GCanvasLog> logVec;
GLuint glID = gcanvas::PixelsBindTexture(rgbaData, GL_RGBA, tw, th, &logVec);
LOG_EXCEPTION_VECTOR(mHooks, mContextId, logVec);
sw = sw > tw ? tw : sw;
sh = sh > th ? th : sh;
sw -= sx;
sh -= sy;
DrawImage(glID, tw, th, sx, sy, sw, sh, x + sx, y + sy, sw, sh);
dirtyW = dirtyW > tw ? tw : dirtyW;
dirtyH = dirtyH > th ? th : dirtyH;
if (glID <= 0) {
LOG_EXCEPTION(mHooks, mContextId, "texture invalid", "<function:%s> textureId=%i",
__FUNCTION__, glID);
return;
}
// drawTexture, but ignore blend, shadow, transform
UseTextureRenderPipeline();
GColorRGBA color = GColorWhite;
SetTexture(glID);
// disable clip
glDisable(GL_DEPTH_TEST);
// TODO IOS blendFunc
#ifdef ANDROID
GCompositeOperation compositeOp = mCurrentState->mGlobalCompositeOp;
GBlendOperationFuncs funcs = GCompositeOperationFuncs(COMPOSITE_OP_COPY);
GBlendOperationFuncs alphaFuncs = GCompositeOperationFuncs(COMPOSITE_OP_COPY);
glBlendFuncSeparate(funcs.source, funcs.destination,
alphaFuncs.source, alphaFuncs.destination);
#endif
PushRectangle(dirtyX + x, dirtyY + y, dirtyW, dirtyH,
dirtyX / tw, dirtyY / th, dirtyW / tw, dirtyH / th, color, GTransformIdentity, is_src_flip_y);
SendVertexBufferToGPU();
SetTexture(InvalidateTextureId);
glDeleteTextures(1, &glID);
#ifdef ANDROID
// rollback clip
glEnable(GL_DEPTH_TEST);
// rollback blend
GBlendOperationFuncs funcs2 = GCompositeOperationFuncs(compositeOp);
GBlendOperationFuncs alphaFuncs2 = GCompositeOperationFuncs(compositeOp);
glBlendFuncSeparate(funcs2.source, funcs2.destination,
alphaFuncs2.source, alphaFuncs2.destination);
#endif
}
int GCanvasContext::BindImage(const unsigned char *rgbaData, GLint format, unsigned int width,

View File

@ -93,7 +93,7 @@ public:
API_EXPORT bool InitializeGLEnvironment();
bool InitializeGLShader();
void ResetStateStack();
void mock();
void BindVertexBuffer();
void ClearGeometryDataBuffers();
API_EXPORT void SendVertexBufferToGPU(const GLenum geometry_type = GL_TRIANGLES);
@ -123,7 +123,7 @@ public:
float GetCurrentAlphaOfStyle(bool isStroke = false);
void SetTexture(int textureId);
bool flagHack=true;
//----------------Push Vertex------------------------
void PushTriangle(GPoint v1, GPoint v2, GPoint v3, GColorRGBA color,
@ -328,15 +328,20 @@ public:
//image
API_EXPORT void DrawImage(int textureId, int textureWidth, int textureHeight,
float sx, float sy, float sw, float sh,
float dx, float dy, float dw, float dh,
bool flipY = false);
float sx, float sy, float sw, float sh,
float dx, float dy, float dw, float dh,
bool flipY = false);
API_EXPORT void DoDrawImage(float w, float h, int TextureId, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, bool flipY = false);
API_EXPORT void PutImageDataFloat(const unsigned char *rgbaData,
int tw, int th, float x, float y,
float dirtyX, float dirtyY, float dirtyW, float dirtyH,
bool is_src_flip_y = false);
API_EXPORT void PutImageData(const unsigned char *rgbaData,
int tw, int th, int x, int y,
int sx, int sy, int sw, int sh,
int dirtyX, int dirtyY, int dirtyW, int dirtyH,
bool is_src_flip_y = false);
API_EXPORT void GetImageData(int x, int y, int width, int height, uint8_t *pixels);
@ -400,6 +405,8 @@ public:
* @param fontManager GFontManager
*/
API_EXPORT void SetFontManager(GFontManager* fontManager);
bool NeedDrawShadow();
void DrawShadow(const GRectf &rect, std::function<void()> drawFun, bool isStroke = false);
@ -414,7 +421,6 @@ protected:
virtual GShader *FindShader(const char *name);
void DoDrawShadowToFBO(GFrameBufferObjectPtr &shadowFbo, float dpr, const GRectf &rect, std::function<void()> draw);
void DoDrawShadowFBOToScreen(GFrameBufferObjectPtr &shadowFbo, const GRectf &rect, std::vector<GPath*>* recoveryClipPath);
void DrawBlur(const GRectf &rect, float blur, std::function<void()> draw, std::vector<GPath*>* recoveryClipPath);

View File

@ -123,6 +123,7 @@ void GCanvasState::ClearStyle() {
delete mFillStyle;
mFillStyle = nullptr;
}
if (mStrokeStyle != nullptr) {
delete mStrokeStyle;
mStrokeStyle = nullptr;

View File

@ -53,6 +53,8 @@ public:
GColorRGBA mStrokeColor;
GFillStyle *mStrokeStyle;
GFillStyle *mCurrentFillStyle;
GColorRGBA mShadowColor;
float mShadowBlur;

View File

@ -40,7 +40,9 @@ typedef enum
COMPOSITE_OP_LIGHTER = 8,
COMPOSITE_OP_COPY = 9,
COMPOSITE_OP_XOR = 10,
COMPOSITE_OP_CLEAR = 11,
COMPOSITE_OP_NONE,
} GCompositeOperation;

View File

@ -12,13 +12,13 @@
#include <sstream>
#include <cstdlib>
#include <unordered_map>
#include "../support/Log.h"
#include <iomanip>
namespace gcanvas {
GColorRGBA StrValueToColorRGBA(const char *value) {
static std::unordered_map<std::string, GColorRGBA> colorMap;
void InitColorMapIfEmpty(std::map<std::string, GColorRGBA>& colorMap) {
if (colorMap.empty()) {
colorMap.insert(std::pair<std::string, GColorRGBA>(
"black", {{0.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}}));
@ -375,515 +375,252 @@ namespace gcanvas {
colorMap.insert(std::pair<std::string, GColorRGBA>(
"transparent_white", {{1.f, 1.f, 1.f, 0.f}}));
}
}
GColorRGBA StrValueToColorRGBA(const char *value) {
static std::map<std::string, GColorRGBA> colorMap;
GColorRGBA c = {{0.0f, 0.0f, 0.0f, 1.0f}};
if (value == nullptr) {
return c;
}
if (value[0] == '#') {
int length = (int) strlen(value);
char str[] = "ffffff";
if (length == 4) {
str[0] = str[1] = value[3];
str[2] = str[3] = value[2];
str[4] = str[5] = value[1];
unsigned int hex =
(unsigned int) (0x00000000 | strtol(str, nullptr, 16));
c.rgba = {(hex & 0xff) / 255.0f, ((hex & 0xffff) >> 8) / 255.0f,
(hex >> 16) / 255.0f, 1.0};
} else if (length == 7) { // #ff00ff format
str[0] = value[5];
str[1] = value[6];
str[2] = value[3];
str[3] = value[4];
str[4] = value[1];
str[5] = value[2];
unsigned int hex =
(unsigned int) (0x00000000 | strtol(str, nullptr, 16));
c.rgba = {(hex & 0xff) / 255.0f, ((hex & 0xffff) >> 8) / 255.0f,
(hex >> 16) / 255.0f, 1.0};
}
} else {
// 按名称query
// std::string colorVal = value;
// colorVal.erase(std::remove(colorVal.begin(), colorVal.end(), ' '), colorVal.end());
// std::transform(colorVal.begin(), colorVal.end(), colorVal.begin(),
// ::tolower);
// value = colorVal.c_str();
auto iter = colorMap.find(value);
if (iter != colorMap.end()) {
return iter->second;
}
// TODO rgba 格式
int length = (int) strlen(value);
if (strncmp(value, "rgb(", 4) == 0 || strncmp(value, "rgba(", 5) == 0) {
int current = 0;
for (int i = 4; i < length && current < 4; i++) {
if (current == 3) {
// If we have an alpha component, copy the rest of the wide
// string into a char array and use atof() to parse it.
char alpha[8] = {0, 0, 0, 0, 0, 0, 0, 0};
for (int j = 0; i + j < length - 1 && j < 7; j++) {
alpha[j] = value[i + j];
}
double d = atof(alpha);
if (d > 1) {
d = 1;
}
c.components[current] = d;
current++;
} else if (isdigit(value[i])) {
c.components[current] =
(c.components[current] * 10 + (value[i] - '0'));
} else if (value[i] == ',' || value[i] == ')') {
c.components[current] /= 255.0f;
current++;
}
}
}
}
StrValueToColorRGBA(value, c);
return c;
}
GColorRGBA StrValueToColorRGBALegacy(const char *value) {
static std::unordered_map<std::string, GColorRGBA> colorMap;
if (colorMap.empty()) {
colorMap.insert(std::pair<std::string, GColorRGBA>(
"black", {{0.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"silver", {{192.0f / 255, 192.0f / 255, 192.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"gray", {{128.0f / 255, 128.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"white", {{255.0f / 255, 255.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"maroon", {{128.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"red", {{255.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"purple", {{128.0f / 255, 0.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"fuchsia", {{255.0f / 255, 0.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"green", {{0.0f / 255, 128.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lime", {{0.0f / 255, 255.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"olive", {{128.0f / 255, 128.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"yellow", {{255.0f / 255, 255.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"navy", {{0.0f / 255, 0.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"blue", {{0.0f / 255, 0.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"teal", {{0.0f / 255, 128.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"aqua", {{0.0f / 255, 255.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"aliceblue", {{240.0f / 255, 248.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"antiquewhite",
{{250.0f / 255, 235.0f / 255, 215.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"aqua", {{0.0f / 255, 255.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"aquamarine", {{127.0f / 255, 255.0f / 255, 212.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"azure", {{240.0f / 255, 255.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"beige", {{245.0f / 255, 245.0f / 255, 220.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"bisque", {{255.0f / 255, 228.0f / 255, 196.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"black", {{0.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"blanchedalmond",
{{255.0f / 255, 235.0f / 255, 205.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"blue", {{0.0f / 255, 0.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"blueviolet", {{138.0f / 255, 43.0f / 255, 226.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"brown", {{165.0f / 255, 42.0f / 255, 42.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"burlywood", {{222.0f / 255, 184.0f / 255, 135.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"cadetblue", {{95.0f / 255, 158.0f / 255, 160.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"chartreuse", {{127.0f / 255, 255.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"chocolate", {{210.0f / 255, 105.0f / 255, 30.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"coral", {{255.0f / 255, 127.0f / 255, 80.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"cornflowerblue",
{{100.0f / 255, 149.0f / 255, 237.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"cornsilk", {{255.0f / 255, 248.0f / 255, 220.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"crimson", {{220.0f / 255, 20.0f / 255, 60.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"cyan", {{0.0f / 255, 255.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkblue", {{0.0f / 255, 0.0f / 255, 139.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkcyan", {{0.0f / 255, 139.0f / 255, 139.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkgoldenrod",
{{184.0f / 255, 134.0f / 255, 11.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkgray", {{169.0f / 255, 169.0f / 255, 169.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkgreen", {{0.0f / 255, 100.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkgrey", {{169.0f / 255, 169.0f / 255, 169.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkkhaki", {{189.0f / 255, 183.0f / 255, 107.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkmagenta", {{139.0f / 255, 0.0f / 255, 139.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkolivegreen",
{{85.0f / 255, 107.0f / 255, 47.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkorange", {{255.0f / 255, 140.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkorchid", {{153.0f / 255, 50.0f / 255, 204.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkred", {{139.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darksalmon", {{233.0f / 255, 150.0f / 255, 122.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkseagreen",
{{143.0f / 255, 188.0f / 255, 143.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkslateblue", {{72.0f / 255, 61.0f / 255, 139.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkslategray", {{47.0f / 255, 79.0f / 255, 79.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkslategrey", {{47.0f / 255, 79.0f / 255, 79.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkturquoise", {{0.0f / 255, 206.0f / 255, 209.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"darkviolet", {{148.0f / 255, 0.0f / 255, 211.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"deeppink", {{255.0f / 255, 20.0f / 255, 147.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"deepskyblue", {{0.0f / 255, 191.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"dimgray", {{105.0f / 255, 105.0f / 255, 105.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"dimgrey", {{105.0f / 255, 105.0f / 255, 105.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"dodgerblue", {{30.0f / 255, 144.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"firebrick", {{178.0f / 255, 34.0f / 255, 34.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"floralwhite", {{255.0f / 255, 250.0f / 255, 240.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"forestgreen", {{34.0f / 255, 139.0f / 255, 34.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"fuchsia", {{255.0f / 255, 0.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"gainsboro", {{220.0f / 255, 220.0f / 255, 220.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"ghostwhite", {{248.0f / 255, 248.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"gold", {{255.0f / 255, 215.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"goldenrod", {{218.0f / 255, 165.0f / 255, 32.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"gray", {{128.0f / 255, 128.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"green", {{0.0f / 255, 128.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"greenyellow", {{173.0f / 255, 255.0f / 255, 47.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"grey", {{128.0f / 255, 128.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"honeydew", {{240.0f / 255, 255.0f / 255, 240.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"hotpink", {{255.0f / 255, 105.0f / 255, 180.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"indianred", {{205.0f / 255, 92.0f / 255, 92.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"indigo", {{75.0f / 255, 0.0f / 255, 130.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"ivory", {{255.0f / 255, 255.0f / 255, 240.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"khaki", {{240.0f / 255, 230.0f / 255, 140.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lavender", {{230.0f / 255, 230.0f / 255, 250.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lavenderblush",
{{255.0f / 255, 240.0f / 255, 245.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lawngreen", {{124.0f / 255, 252.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lemonchiffon",
{{255.0f / 255, 250.0f / 255, 205.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightblue", {{173.0f / 255, 216.0f / 255, 230.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightcoral", {{240.0f / 255, 128.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightcyan", {{224.0f / 255, 255.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightgoldenrodyellow",
{{250.0f / 255, 250.0f / 255, 210.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightgray", {{211.0f / 255, 211.0f / 255, 211.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightgreen", {{144.0f / 255, 238.0f / 255, 144.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightgrey", {{211.0f / 255, 211.0f / 255, 211.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightpink", {{255.0f / 255, 182.0f / 255, 193.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightsalmon", {{255.0f / 255, 160.0f / 255, 122.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightseagreen",
{{32.0f / 255, 178.0f / 255, 170.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightskyblue",
{{135.0f / 255, 206.0f / 255, 250.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightslategray",
{{119.0f / 255, 136.0f / 255, 153.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightslategrey",
{{119.0f / 255, 136.0f / 255, 153.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightsteelblue",
{{176.0f / 255, 196.0f / 255, 222.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lightyellow", {{255.0f / 255, 255.0f / 255, 224.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"lime", {{0.0f / 255, 255.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"limegreen", {{50.0f / 255, 205.0f / 255, 50.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"linen", {{250.0f / 255, 240.0f / 255, 230.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"magenta", {{255.0f / 255, 0.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"maroon", {{128.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumaquamarine",
{{102.0f / 255, 205.0f / 255, 170.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumblue", {{0.0f / 255, 0.0f / 255, 205.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumorchid", {{186.0f / 255, 85.0f / 255, 211.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumpurple",
{{147.0f / 255, 112.0f / 255, 219.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumseagreen",
{{60.0f / 255, 179.0f / 255, 113.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumslateblue",
{{123.0f / 255, 104.0f / 255, 238.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumspringgreen",
{{0.0f / 255, 250.0f / 255, 154.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumturquoise",
{{72.0f / 255, 209.0f / 255, 204.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mediumvioletred",
{{199.0f / 255, 21.0f / 255, 133.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"midnightblue", {{25.0f / 255, 25.0f / 255, 112.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mintcream", {{245.0f / 255, 255.0f / 255, 250.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"mistyrose", {{255.0f / 255, 228.0f / 255, 225.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"moccasin", {{255.0f / 255, 228.0f / 255, 181.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"navajowhite", {{255.0f / 255, 222.0f / 255, 173.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"navy", {{0.0f / 255, 0.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"oldlace", {{253.0f / 255, 245.0f / 255, 230.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"olive", {{128.0f / 255, 128.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"olivedrab", {{107.0f / 255, 142.0f / 255, 35.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"orange", {{255.0f / 255, 165.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"orangered", {{255.0f / 255, 69.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"orchid", {{218.0f / 255, 112.0f / 255, 214.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"palegoldenrod",
{{238.0f / 255, 232.0f / 255, 170.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"palegreen", {{152.0f / 255, 251.0f / 255, 152.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"paleturquoise",
{{175.0f / 255, 238.0f / 255, 238.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"palevioletred",
{{219.0f / 255, 112.0f / 255, 147.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"papayawhip", {{255.0f / 255, 239.0f / 255, 213.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"peachpuff", {{255.0f / 255, 218.0f / 255, 185.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"peru", {{205.0f / 255, 133.0f / 255, 63.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"pink", {{255.0f / 255, 192.0f / 255, 203.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"plum", {{221.0f / 255, 160.0f / 255, 221.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"powderblue", {{176.0f / 255, 224.0f / 255, 230.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"purple", {{128.0f / 255, 0.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"red", {{255.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"rosybrown", {{188.0f / 255, 143.0f / 255, 143.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"royalblue", {{65.0f / 255, 105.0f / 255, 225.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"saddlebrown", {{139.0f / 255, 69.0f / 255, 19.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"salmon", {{250.0f / 255, 128.0f / 255, 114.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"sandybrown", {{244.0f / 255, 164.0f / 255, 96.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"seagreen", {{46.0f / 255, 139.0f / 255, 87.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"seashell", {{255.0f / 255, 245.0f / 255, 238.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"sienna", {{160.0f / 255, 82.0f / 255, 45.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"silver", {{192.0f / 255, 192.0f / 255, 192.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"skyblue", {{135.0f / 255, 206.0f / 255, 235.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"slateblue", {{106.0f / 255, 90.0f / 255, 205.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"slategray", {{112.0f / 255, 128.0f / 255, 144.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"slategrey", {{112.0f / 255, 128.0f / 255, 144.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"snow", {{255.0f / 255, 250.0f / 255, 250.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"springgreen", {{0.0f / 255, 255.0f / 255, 127.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"steelblue", {{70.0f / 255, 130.0f / 255, 180.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"tan", {{210.0f / 255, 180.0f / 255, 140.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"teal", {{0.0f / 255, 128.0f / 255, 128.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"thistle", {{216.0f / 255, 191.0f / 255, 216.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"tomato", {{255.0f / 255, 99.0f / 255, 71.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"turquoise", {{64.0f / 255, 224.0f / 255, 208.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"violet", {{238.0f / 255, 130.0f / 255, 238.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"wheat", {{245.0f / 255, 222.0f / 255, 179.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"white", {{255.0f / 255, 255.0f / 255, 255.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"whitesmoke", {{245.0f / 255, 245.0f / 255, 245.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"yellow", {{255.0f / 255, 255.0f / 255, 0.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"yellowgreen", {{154.0f / 255, 205.0f / 255, 50.0f / 255, 1.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"transparent", {{0, 0, 0, 0.0f}}));
colorMap.insert(std::pair<std::string, GColorRGBA>(
"transparent_white", {{1.f, 1.f, 1.f, 0.f}}));
}
GColorRGBA c = {{0.0f, 0.0f, 0.0f, 1.0f}};
if (value == nullptr) {
return c;
}
// 按名称query
std::string colorVal = value;
colorVal.erase(std::remove(colorVal.begin(), colorVal.end(), ' '), colorVal.end());
std::transform(colorVal.begin(), colorVal.end(), colorVal.begin(),
::tolower);
value = colorVal.c_str();
auto iter = colorMap.find(value);
if (iter != colorMap.end()) {
return iter->second;
}
/**
* support format:
* normal: rgb(100, 100, 100)
* percent: rgb(100%, 10%, 10%)
* no end: rgb(100, 100, 100
* space seperate: rgb(100 100 100)
* alpha: rgba(100 100 100 / 0.4)
*/
bool HandleBraceRGBAColor(char* value, GColorRGBA& output) {
int length = (int) strlen(value);
char str[] = "ffffff";
int current = 0;
std::string temp = "";
float colorV;
// #f0f format
if (length == 4) {
str[0] = str[1] = value[3];
str[2] = str[3] = value[2];
str[4] = str[5] = value[1];
unsigned int hex =
(unsigned int) (0x00000000 | strtol(str, nullptr, 16));
c.rgba = {(hex & 0xff) / 255.0f, ((hex & 0xffff) >> 8) / 255.0f,
(hex >> 16) / 255.0f, 1.0};
// separator format
bool isSpaceSep = false;
bool isCommaSep = false;
bool isPercent = false;
int start = 4;
if (value[start] == '(') {
start = 5;
}
// #ff00ff format
else if (length == 7) {
str[0] = value[5];
str[1] = value[6];
str[2] = value[3];
str[3] = value[4];
str[4] = value[1];
str[5] = value[2];
unsigned int hex =
(unsigned int) (0x00000000 | strtol(str, nullptr, 16));
c.rgba = {(hex & 0xff) / 255.0f, ((hex & 0xffff) >> 8) / 255.0f,
(hex >> 16) / 255.0f, 1.0};
} else { // assume rgb(255,0,255) or rgba(255,0,255,0.5) format
if (strncmp(value, "rgb(", 4) == 0 || strncmp(value, "rgba(", 5) == 0) {
int current = 0;
for (int i = 4; i < length && current < 4; i++) {
if (current == 3) {
// If we have an alpha component, copy the rest of the wide
// string into a char array and use atof() to parse it.
char alpha[8] = {0, 0, 0, 0, 0, 0, 0, 0};
for (int j = 0; i + j < length - 1 && j < 7; j++) {
alpha[j] = value[i + j];
}
double d = atof(alpha);
if (d > 1) {
d = 1;
}
c.components[current] = d;
current++;
} else if (isdigit(value[i])) {
c.components[current] =
(c.components[current] * 10 + (value[i] - '0'));
} else if (value[i] == ',' || value[i] == ')') {
c.components[current] /= 255.0f;
current++;
bool endFlag;
bool startFlag = false;
for (int i = start; i < length && current < 4; i++) {
if (current == 3) { // parse alpha
// If we have an alpha component, copy the rest of the wide
// string into a char array and use atof() to parse it.
char alpha[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int offset = 0;
int k = 0;
char lastChar = '\0';
for (int j = 0; (i + j) <= length - 1 && j <= 7; j++) {
offset = i + j;
if (isdigit(value[offset]) || value[offset] == '.' || value[offset] == '%' || value[offset] == '-') {
alpha[k] = value[i + j];
lastChar = alpha[k];
k++;
}
}
if (alpha[0] == '\0') { // wrong format
return false;
}
size_t ret;
std::stof(alpha, &ret);
double d = atof(alpha);
if (lastChar == '%') {
d = d / 100;
}
if (d > 1) {
d = 1;
}
output.components[current] = d;
current ++;
// LOG_E("HandleBraceRGBAColor(alpha):str=%s, value=%f", alpha, d);
} else { // not alpha
// LOG_E("iterate value[%i]=%i", i, value[i]);
if (isdigit(value[i]) || value[i] == '.' || value[i] == '%' || value[i] == '-' || value[i] == '+') {
// LOG_E("set start=true push back %c", value[i]);
if (!startFlag) {
startFlag = true;
}
// reset not end
endFlag = false;
temp.push_back(value[i]);
} else if (value[i] == ',' || value[i] == ')' || isspace(value[i])) { // end
// LOG_E("is , ) or space: c=%c, set end=true", value[i]);
endFlag = true;
} else { // wrong format
// LOG_E("wrong digit: %c, exit", value[i]);
return false;
}
if (i == length - 1) {
endFlag = true;
}
if (startFlag && endFlag) {
// check is all percent?
char lastChar = temp.at(temp.length() - 1);
if (current == 0) {
if (value[i] == ',') {
isCommaSep = true;
} else if (isspace(value[i])) {
isSpaceSep = true;
}
if (lastChar == '%') {
isPercent = true;
}
} else {
if (lastChar != '%' && isPercent) { // not percent consistent
return false;
}
if (value[i] == ',' && !isCommaSep) { // not comma consistent
return false;
}
if (isspace(value[i]) && !isSpaceSep) { // not space consistent
return false;
}
}
colorV = (float)atof(temp.data());
if (isPercent) {
colorV = colorV < 0 ? 0 : (colorV > 100 ? 100 : colorV);
output.components[current] = colorV / 100;
} else {
colorV = colorV < 0 ? 0 : (colorV > 255 ? 255 : colorV);
output.components[current] = colorV / 255.0f;
}
//LOG_E("HandleBraceRGBAColor(RGB): temp=%s, current=%i, result=%f",
// temp.data(), current, output.components[current]);
current++;
temp = "";
startFlag = false;
endFlag = false;
}
}
}
return c;
if (current < 3) { // not match count, at least include r,g,b all
return false;
}
return true;
}
GColorRGBA ParseRGBAFullString(char value[8]) {
GColorRGBA ret;
ParseRGBAFullString(value, ret);
return ret;
}
void ParseRGBAFullString(char value[8], GColorRGBA& output) {
unsigned long hex = 0x00000000 | strtoul(value, nullptr, 16);
output.rgba = {(hex >> 24) / 255.0f, ((hex & 0xff0000) >> 16) / 255.0f,
((hex & 0xff00) >> 8) / 255.0f, (hex & 0xff) / 255.0f};
}
bool StrValueToColorRGBA(const char *value, GColorRGBA& output) {
static std::map<std::string, GColorRGBA> colorMap;
InitColorMapIfEmpty(colorMap);
output = {{0.0f, 0.0f, 0.0f, 1.0f}};
if (value == nullptr) {
return false;
}
// LOG_E("StrValueToColorRGBA: input=%s", value);
if (value[0] == '#') {
int length = (int) strlen(value);
char str[] = "ffffffff";
// check value valid?
for (int i = 1; i < length; i++) {
if (!((value[i] >= '0' && value[i] <= '9') || (value[i] >= 'a' && value[i] <= 'f')
|| (value[i] >= 'A' && value[i] <= 'F'))) { // wrong format
// LOG_E("check # wrong format: %c=", value[i]);
return false;
}
}
if (length == 4) {
str[0] = str[1] = value[1];
str[2] = str[3] = value[2];
str[4] = str[5] = value[3];
output = ParseRGBAFullString(str);
} else if (length == 5) {
str[0] = str[1] = value[1];
str[2] = str[3] = value[2];
str[4] = str[5] = value[3];
str[6] = str[7] = value[4];
output = ParseRGBAFullString(str);
} else if (length == 7) { // #RRGGBB format
str[0] = value[1];
str[1] = value[2];
str[2] = value[3];
str[3] = value[4];
str[4] = value[5];
str[5] = value[6];
output = ParseRGBAFullString(str);
} else if (length == 9) { // #RRGGBBAA
memcpy(str, value + 1, 8);
output = ParseRGBAFullString(str);
} else {
return false;
}
// LOG_E("StrValueToColorRGBA: input=%s, output=%f %f %f %f", str,
// output.components[0], output.components[1], output.components[2], output.components[3]);
return true;
} else {
std::string colorVal = value;
colorVal = Trim(value);
// colorVal.erase(std::remove(colorVal.begin(), colorVal.end(), ' '), colorVal.end());
std::transform(colorVal.begin(), colorVal.end(), colorVal.begin(), ::tolower);
value = colorVal.c_str();
// match color name
auto iter = colorMap.find(value);
if (iter != colorMap.end()) {
output = iter->second;
return true;
}
// handle hsla( format color (not support now)
if (strncmp(value, "hsl(", 4) == 0 || strncmp(value, "hsla(", 5) == 0) {
return false;
}
// handle rgb( | rgba( format
if (strncmp(value, "rgb(", 4) == 0 || strncmp(value, "rgba(", 5) == 0) {
return HandleBraceRGBAColor((char*)value, output);
}
// parse error
return false;
}
}
std::string Trim(const std::string& str, const std::string& whitespace) {
const auto strBegin = str.find_first_not_of(whitespace);
if (strBegin == std::string::npos) {
return ""; // no content
}
const auto strEnd = str.find_last_not_of(whitespace);
const auto strRange = strEnd - strBegin + 1;
return str.substr(strBegin, strRange);
}
@ -895,6 +632,22 @@ namespace gcanvas {
return ss.str();
}
/**
* convert #RRGGBBAA format
*/
std::string ColorToRGBASharpString(const GColorRGBA &color) {
std::ostringstream ss;
ss << "#" << std::setfill ('0') << std::setw(2) << std::hex << (int) (color.rgba.r * 255)
<< std::setfill ('0') << std::setw(2) << std::hex << (int) (color.rgba.g * 255)
<< std::setfill ('0') << std::setw(2) << std::hex << (int) (color.rgba.b * 255);
if (color.rgba.a < 1.0f) {
ss << std::setfill ('0') << std::setw(2) << std::hex << (int) (color.rgba.a * 255);
}
return ss.str();
}
/**
* int (RGBA) convert to GColorRGBA
*/
@ -909,4 +662,50 @@ namespace gcanvas {
return c;
}
// /*
// * H(Hue): 0 - 360 degree (integer)
// * S(Saturation): 0 - 1.00 (double)
// * V(Value): 0 - 1.00 (double)
// *
// * output[3]: Output, array size 3, int
// */
// void HSVtoRGB(int H, double S, double V, int output[3]) {
// double C = S * V;
// double X = C * (1 - abs(fmod(H / 60.0, 2) - 1));
// double m = V - C;
// double Rs, Gs, Bs;
//
// if(H >= 0 && H < 60) {
// Rs = C;
// Gs = X;
// Bs = 0;
// } else if(H >= 60 && H < 120) {
// Rs = X;
// Gs = C;
// Bs = 0;
// } else if(H >= 120 && H < 180) {
// Rs = 0;
// Gs = C;
// Bs = X;
// } else if(H >= 180 && H < 240) {
// Rs = 0;
// Gs = X;
// Bs = C;
// } else if(H >= 240 && H < 300) {
// Rs = X;
// Gs = 0;
// Bs = C;
// } else {
// Rs = C;
// Gs = 0;
// Bs = X;
// }
//
// output[0] = (int)((Rs + m) * 255);
// output[1] = (int)((Gs + m) * 255);
// output[2] = (int)((Bs + m) * 255);
// }
}

View File

@ -17,17 +17,29 @@
#define GColorTransparentWhite GColorRGBA({1.0,1.0,1.0,0})
#define GColorWhite GColorRGBA({1.0,1.0,1.0,1.0})
namespace gcanvas{
API_EXPORT GColorRGBA StrValueToColorRGBA(const char *value);
API_EXPORT GColorRGBA StrValueToColorRGBALegacy(const char *value);
API_EXPORT bool StrValueToColorRGBA(const char *value, GColorRGBA& output);
API_EXPORT GColorRGBA ParseRGBAFullString(char value[8]);
API_EXPORT void ParseRGBAFullString(char value[8], GColorRGBA&);
API_EXPORT GColorRGBA IntValueToColorRGBA(int value);
API_EXPORT std::string ColorToString(const GColorRGBA &color);
API_EXPORT std::string ColorToRGBASharpString(const GColorRGBA &color);
std::string Trim(const std::string& str, const std::string& whitespace = " \t");
}

View File

@ -33,6 +33,11 @@ public:
bool IsLinearGradient() { return mStyle == STYLE_LINEAR_GRADIENT; }
bool IsRadialGradient() { return mStyle == STYLE_RADIAL_GRADIENT; }
bool IsDefault() { return mStyle == STYLE_UNDEFINED; }
virtual bool IsSameAs(GFillStyle *otherStyle)
{
return otherStyle && mStyle == otherStyle->mStyle;
}
virtual ~GFillStyle(){};
@ -68,6 +73,20 @@ public:
new FillStylePattern(mTextureListId, mPattern);
return ptr;
}
bool IsSameAs(GFillStyle *otherStyle)
{
if (GFillStyle::IsSameAs(otherStyle)) {
if (typeid(*otherStyle) == typeid(FillStylePattern)) {
FillStylePattern *patternStyle = (FillStylePattern *)otherStyle;
return mPattern == patternStyle->mPattern
&& mTextureListId == patternStyle->mTextureListId
&& mTextureWidth == patternStyle->mTextureWidth
&& mTextureHeight == patternStyle->mTextureHeight;
}
}
return false;
}
private:
std::string mPattern;
@ -123,6 +142,34 @@ public:
}
return nullptr;
}
bool IsSameAs(GFillStyle *otherStyle)
{
if (GFillStyle::IsSameAs(otherStyle)) {
if (typeid(*otherStyle) == typeid(FillStyleLinearGradient)) {
FillStyleLinearGradient *linearGradientStyle = (FillStyleLinearGradient *)otherStyle;
bool ret = PointEqualToPoint(mStartPos, linearGradientStyle->mStartPos)
&& PointEqualToPoint(mEndPos, linearGradientStyle->mEndPos)
&& mStopCount == linearGradientStyle->mStopCount;
if (ret) {
for (int i = 0; i < mStopCount; ++i) {
ColorStop colorStop = mStops[i];
ColorStop colorStop2 = linearGradientStyle->mStops[i];
if (colorStop.pos != colorStop2.pos
|| colorStop.color.rgba.r != colorStop2.color.rgba.r
|| colorStop.color.rgba.g != colorStop2.color.rgba.g
|| colorStop.color.rgba.b != colorStop2.color.rgba.b
|| colorStop.color.rgba.a != colorStop2.color.rgba.a) {
ret = false;
break;
}
}
}
return ret;
}
}
return false;
}
private:
GPoint mStartPos, mEndPos;
@ -182,6 +229,41 @@ public:
*ptr = *this;
return ptr;
}
bool IsSameAs(GFillStyle *otherStyle)
{
if (GFillStyle::IsSameAs(otherStyle)) {
if (typeid(*otherStyle) == typeid(FillStyleRadialGradient)) {
FillStyleRadialGradient *radialGradientStyle = (FillStyleRadialGradient *)otherStyle;
bool ret = true;
// 比较两个圆形参数是否一致
for (int i = 0; i < 3; ++i) {
if (mStart[i] != radialGradientStyle->mStart[i] || mEnd[i] != radialGradientStyle->mEnd[i]) {
ret = false;
break;
}
}
// 比较颜色参数是否一致
ret &= mStopCount == radialGradientStyle->mStopCount;
if (ret) {
for (int i = 0; i < mStopCount; ++i) {
ColorStop colorStop = mStops[i];
ColorStop colorStop2 = radialGradientStyle->mStops[i];
if (colorStop.pos != colorStop2.pos
|| colorStop.color.rgba.r != colorStop2.color.rgba.r
|| colorStop.color.rgba.g != colorStop2.color.rgba.g
|| colorStop.color.rgba.b != colorStop2.color.rgba.b
|| colorStop.color.rgba.a != colorStop2.color.rgba.a) {
ret = false;
break;
}
}
}
return ret;
}
}
return false;
}
private:
float mStart[3], mEnd[3];

View File

@ -64,14 +64,13 @@ bool GFontManager::LoadGlyphToTexture(GGlyph &glyph) {
texture = GetOrCreateFontTexture();
flag = PrepareGlyphTexture((int)glyph.width, (int)glyph.height, rect);
}
if(texture==nullptr){
printf("GetOrCreateFontTexture is null \n");
}
if (!flag) {
return false;
} else {
unsigned int texWidth = texture->GetWidth();
unsigned int texHeight = texture->GetHeight();
if (glyph.bitmapBuffer != nullptr) {
texture->UpdateTexture(glyph.bitmapBuffer, rect.x, rect.y, rect.width, rect.height);
glyph.texture = texture;

View File

@ -20,8 +20,8 @@
class GCanvasContext;
#define FontTextureWidth 2048
#define FontTextureHeight 2048
#define FontTextureWidth 1024
#define FontTextureHeight 1024
namespace gcanvas
{

View File

@ -18,18 +18,13 @@
namespace gcanvas {
GFontStyle::GFontStyle(const char *font, float ratio) : mFontName(font ? font : "") {
if (font != nullptr) {
mFullFontStyle = font;
} else {
mFullFontStyle = "";
}
mFullFontStyle = "";
mStyle = Style::NORMAL;
mVariant = Variant::NORMAL;
mWeight = Weight::NORMAL;
mSize = 12 * ratio;
mRatio = ratio;
mSize = 10 * ratio;
mFamily = "sans-serif";
mRatio = ratio;
mAscender = -1;
mDescender = -1;
@ -39,6 +34,23 @@ namespace gcanvas {
}
GFontStyle::GFontStyle(const char *font, Style style, Variant variant, Weight weight,
float fontSize, std::string& fontFamily, float ratio) {
mFontName = font ? font : "";
mFullFontStyle = font ? font : "";
mStyle = style;
mVariant = variant;
mWeight = weight;
mSize = fontSize * ratio;
mRatio = ratio;
mFamily = fontFamily;
mAscender = -1;
mDescender = -1;
}
GFontStyle::~GFontStyle() {}
std::string GFontStyle::GetName() {
@ -52,91 +64,153 @@ namespace gcanvas {
mFullFontStyle = "";
}
if (font != nullptr) {
float fSize = 0;
ParseFields(font, mStyle, mVariant, mWeight, fSize, mFamily);
if (fSize > 0) {
mSize = fSize * mRatio;
}
}
}
GFontStyle* GFontStyle::Parse(const char *font, float deviceDensity) {
Style style = Style::INVALID;
Weight weight = Weight::INVALID;
Variant variant = Variant::INVALID;
std::string outFontFamily = "";
float fontStyleSize = 0;
ParseFields(font, style, variant, weight, fontStyleSize, outFontFamily);
if (style == Style::INVALID || weight == Weight::INVALID || variant == Variant::INVALID
|| outFontFamily.empty() || fontStyleSize == 0) {
return nullptr;
}
std::string formatFont = font;
std::transform(formatFont.begin(), formatFont.end(), formatFont.begin(), ::tolower);
GFontStyle* ret = new GFontStyle(formatFont.data(), style, variant, weight, fontStyleSize, outFontFamily, deviceDensity);
return ret;
}
/**
* [font-style] [font-variant] [font-weight] (font-size) (font-family)
* font-size, font-family is required, If one of the other values is missing, their default value are used
* default table:
* font-style: normal (normal|italic|oblique)
* font-variant: normal (normal|small-caps)
* font-weight: normal (normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)
*/
void GFontStyle::ParseFields(const char *font, Style& style, Variant& variant, Weight& weight,
float& fontStyleSize, std::string& outFontFamily) {
std::string newFont(font);
GStrSeparator sepStr;
short ct = sepStr.SepStrBySpace((char *) newFont.c_str(), 5);
char **parts = sepStr.GetSepArray();
int index = 0;
while (index < ct) {
std::string curStr = parts[index];
std::transform(curStr.begin(), curStr.end(), curStr.begin(), ::tolower);
const char *curCStr = curStr.c_str();
if (strcmp("normal", curCStr) == 0 ||
strcmp("400", curCStr) == 0) {
// "normal" should be skipped in any case
} else if (strcmp("oblique", curCStr) == 0) {
mStyle = Style::OBLIQUE;
} else if (strcmp("italic", curCStr) == 0) {
mStyle = Style::ITALIC;
} else if (strcmp("small-caps", curCStr) == 0) {
mVariant = Variant::SMALL_CAPS;
} else if (strcmp("bold", curCStr) == 0 ||
strcmp("700", curCStr) == 0) {
mWeight = Weight::BOLD;
} else if (strcmp("bolder", curCStr) == 0) {
mWeight = Weight::BOLDER;
} else if (strcmp("lighter", curCStr) == 0) {
mWeight = Weight::LIGHTER;
} else if (strcmp("100", curCStr) == 0) {
mWeight = Weight::THIN;
} else if (strcmp("200", curCStr) == 0) {
mWeight = Weight::EXTRA_LIGHT;
} else if (strcmp("300", curCStr) == 0) {
mWeight = Weight::LIGHT;
} else if (strcmp("500", curCStr) == 0) {
mWeight = Weight::MEDIUM;
} else if (strcmp("600", curCStr) == 0) {
mWeight = Weight::SEMI_BOLD;
} else if (strcmp("800", curCStr) == 0) {
mWeight = Weight::EXTRA_BOLD;
} else if (strcmp("900", curCStr) == 0) {
mWeight = Weight::BLACK;
} else {
std::string fontFamily = "";
std::string fontSize(curCStr);
auto pos = fontSize.find("px");
if (pos != std::string::npos) {
auto len = strlen(curCStr);
if (pos == (len - 2)) {
char *endPtr = nullptr;
mSize = strtof(curCStr, &endPtr);
mSize *= mRatio;
if (++index < ct) {
fontFamily = parts[index];
}
}
if (ct >= 2) {
// parse fontStyle & fontSize
std::string fontSize = parts[ct - 2];
std::transform(fontSize.begin(), fontSize.end(), fontSize.begin(), ::tolower);
auto pos = fontSize.find("px");
if (pos != std::string::npos) {
if (pos == fontSize.length() - 2) {
char *endPtr = nullptr;
fontStyleSize = strtof(fontSize.data(), &endPtr);
}
pos = fontSize.find("pt");
if (pos != std::string::npos) {
auto len = strlen(curCStr);
if (pos == (len - 2)) {
char *endPtr = nullptr;
mSize = strtof(curCStr, &endPtr) * 4 / 3;
mSize *= mRatio;
if (++index < ct) {
fontFamily = parts[index];
}
}
}
if (fontFamily.length() > 0) {
fontFamily.erase(std::remove(fontFamily.begin(), fontFamily.end(), '\"'),
fontFamily.end());
std::transform(fontFamily.begin(), fontFamily.end(), fontFamily.begin(),
::tolower);
mFamily = fontFamily;
}
pos = fontSize.find("pt");
if (pos != std::string::npos) {
if (pos == (fontSize.length() - 2)) {
char *endPtr = nullptr;
fontStyleSize = strtof(fontSize.data(), &endPtr) * 4 / 3;
}
}
++index;
}
if (mSize == 0) {
mSize = 12 * mRatio;
std::string fontFamily = parts[ct - 1];
if (fontFamily.length() > 0) {
fontFamily.erase(std::remove(fontFamily.begin(), fontFamily.end(), '\"'),
fontFamily.end());
std::transform(fontFamily.begin(), fontFamily.end(), fontFamily.begin(),
::tolower);
// 不支持 initial|inherit|default, 排查特殊符号
if (fontFamily != "initial" && fontFamily != "inherit" && fontFamily != "default"
&& fontFamily.find("{") == std::string::npos && fontFamily.find("{") == std::string::npos) {
outFontFamily = fontFamily;
}
}
// parse font-weight
if (ct >= 3) {
std::string weightStr = parts[ct - 3];
std::transform(weightStr.begin(), weightStr.end(), weightStr.begin(), ::tolower);
if (weightStr == "normal" || weightStr == "400") {
weight = Weight::NORMAL;
} else if (weightStr == "bold" || weightStr == "700") {
weight = Weight::BOLD;
} else if (weightStr == "bolder") {
weight = Weight::BOLDER;
} else if (weightStr == "lighter") {
weight = Weight::LIGHTER;
} else if (weightStr == "100") {
weight = Weight::THIN;
} else if (weightStr == "200") {
weight = Weight::EXTRA_LIGHT;
} else if (weightStr == "300") {
weight = Weight::LIGHT;
} else if (weightStr == "500") {
weight = Weight::MEDIUM;
} else if (weightStr == "600") {
weight = Weight::SEMI_BOLD;
} else if (weightStr == "800") {
weight = Weight::EXTRA_BOLD;
} else if (weightStr == "900") {
weight = Weight::BLACK;
} else {
weight = Weight::INVALID;
}
} else {
weight = Weight::NORMAL;
}
// parse variant
if (ct >= 4) {
std::string variantStr = parts[ct - 4];
std::transform(variantStr.begin(), variantStr.end(), variantStr.begin(), ::tolower);
if (variantStr == "normal") {
variant = Variant::NORMAL;
} else if (variantStr == "small-caps") {
variant = Variant::SMALL_CAPS;
} else {
variant = Variant::INVALID;
}
} else {
variant = Variant::NORMAL;
}
// parse style
if (ct == 5) {
std::string styleStr = parts[ct - 5];
std::transform(styleStr.begin(), styleStr.end(), styleStr.begin(), ::tolower);
if (styleStr == "normal") {
style = Style::NORMAL;
} else if (styleStr == "oblique") {
style = Style::OBLIQUE;
} else if (styleStr == "italic") {
style = Style::ITALIC;
} else {
style = Style::INVALID;
}
} else {
style = Style::NORMAL;
}
}
}
}

View File

@ -22,12 +22,12 @@ namespace gcanvas
class GFontStyle final
{
public:
API_EXPORT GFontStyle(const char *font = nullptr, float ratio = 1.0);
API_EXPORT ~GFontStyle();
enum class Style
{
INVALID,
NORMAL = 0x0001,
ITALIC = 0x0002,
OBLIQUE = 0x0004
@ -35,12 +35,14 @@ public:
enum class Variant
{
INVALID,
NORMAL = 0x0008,
SMALL_CAPS = 0x0010
};
enum class Weight
{
INVALID,
LIGHTER = 0x0020,
THIN = 0x0040, // 100
EXTRA_LIGHT = 0x0080, // 200
@ -54,6 +56,17 @@ public:
BLACK = 0x8000 // 900
};
API_EXPORT GFontStyle(const char *font = nullptr, float ratio = 1.0);
API_EXPORT GFontStyle(const char *font, Style style, Variant variant,
Weight weight, float fontSize, std::string& fontFamily, float ratio);
API_EXPORT ~GFontStyle();
Style GetStyle() { return mStyle; }
Variant GetVariant() { return mVariant; }
@ -74,9 +87,17 @@ public:
float GetDescender() { return mDescender; }
void SetAscender(float as) { mAscender = as;}
void SetDescender(float des) { mDescender = des;}
static GFontStyle* Parse(const char *font, float deviceDensity);
private:
void Initialize(const char *font);
static void ParseFields(const char *font,
Style& style, Variant& variant, Weight& weight, float& fontStyleSize, std::string& outFontFamily);
std::string mFullFontStyle;
std::string mFontName;
Style mStyle;

View File

@ -20,7 +20,6 @@ const GGlyph *GGlyphCache::GetGlyph(const std::string& fontName,
GGlyphMap::iterator iter = mGlyphs.find(make_tuple(fontName, charCode, glyphKey, isStroke));
if (iter != mGlyphs.end()) {
if (autoLoadTexture) {
printf("the autoLoadTexture \n");
if (!iter->second.texture) {
// if texture is empty, we save glyph to texture and then get textureId
if (!mFontManager.LoadGlyphToTexture(iter->second)) {

View File

@ -13,6 +13,9 @@
#ifndef _WIN32
#ifdef ANDROID
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES 1
#endif
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <GLES2/gl2ext.h>

View File

@ -88,6 +88,28 @@ namespace gcanvas {
}
}
void FlipYPixels(int width, int height, int *inPixels, int *outPixels) {
GLuint *pixs = (GLuint *) inPixels;
uint8_t *src = (uint8_t *) pixs + (height - 1) * width * 4;
uint8_t *dest = (uint8_t *) outPixels;
// 扫描转置(OpenGl:左上->右下 Bitmap:左下->右上)
for (int y = 0; y < height; y++) {
memcpy(dest, src, (size_t)width * 4);
src -= (width * 4);
dest += (width * 4);
}
// return pixs;
// for (int y = 0; y < height; ++y) {
// int revertY = height - y - 1;
// for (int x = 0; x < width; ++x) {
// RGBA pixel;
// outPixels[y * width + x] = GetPixel(inPixels, x, revertY, width, height);
// }
// }
}
//////////////////////////////////////////////////////////////////////////////
/// Pixels BindTexture
//////////////////////////////////////////////////////////////////////////////

View File

@ -15,9 +15,16 @@
#include <vector>
namespace gcanvas{
GLuint PixelsBindTexture(const unsigned char *rgbaData, GLint format, unsigned int width,
unsigned int height, std::vector<GCanvasLog> *errVec = nullptr);
void PixelsSampler(int inWidth, int inHeight, int *inPixels, int outWidth, int outHeight, int *outPixels);
void FlipYPixels(int width, int height, int *inPixels, int *outPixels) ;
}
#endif /* GCANVAS_GLUTIL_H */

View File

@ -266,7 +266,6 @@ void ShadowShader::calculateAttributesLocations()
{
mPositionSlot = glGetAttribLocation(mHandle, "a_position");
mTexcoordSlot = glGetAttribLocation(mHandle, "a_texCoord");
mColorSlot = glGetAttribLocation(mHandle, "a_srcColor");
mTransfromSlot = glGetUniformLocation(mHandle, "u_modelView");
mTextureSamplerSlot = glGetUniformLocation(mHandle, "u_texture");
mShadowColorSlot = glGetUniformLocation(mHandle, "u_shadowColor");

View File

@ -118,6 +118,7 @@ public:
void SetHasTexture(bool value)
{
if (mHasTextureFlag != value)
{
mHasTextureFlag = value;

View File

@ -2,15 +2,12 @@
#define SHADOW_SHADER_VS "\
attribute vec4 a_position; \n\
attribute vec4 a_srcColor; \n\
attribute vec2 a_texCoord; \n\
uniform mat4 u_modelView; \n\
varying vec2 v_texCoord; \n\
varying vec4 v_desColor; \n\
void main() \n\
{ \n\
gl_Position = u_modelView * a_position; \n\
v_desColor = a_srcColor; \n\
v_texCoord = a_texCoord; \n\
}"

View File

@ -648,6 +648,7 @@ void GPath::Stroke(GCanvasContext *context, GColorRGBA color, std::vector<GVerte
void GPath::Stroke(GCanvasContext *context) {
context->SetTexture(InvalidateTextureId);
GColorRGBA color = BlendStrokeColor(context);
std::vector<GVertex> vertexVec;
if (color.rgba.a < 1.0) { //transparent, use stencil buffer
Stroke(context, color, &vertexVec);

View File

@ -38,7 +38,7 @@ struct GPathCmd {
~GPathCmd() {
if (data != nullptr) {
free (data);
delete[] data;
}
}

View File

@ -78,6 +78,11 @@ static inline GPoint PointNormalize(GPoint v)
return v;
}
static inline bool PointEqualToPoint(const GPoint &pt1, const GPoint &pt2)
{
return pt1.x == pt2.x && pt1.y == pt2.y;
}
struct GRectf
{
bool isTransformed = false; //坐标是否经过transform变换

View File

@ -21,6 +21,7 @@ void GCanvasContext::DrawTextWithLength(const char *text, int strLength, float x
const GCompositeOperation old_op = mCurrentState->mGlobalCompositeOp;
DoSetGlobalCompositeOperation(COMPOSITE_OP_SOURCE_OVER, COMPOSITE_OP_SOURCE_OVER);
// scaleWidth
float scaleWidth = 1.0;
if (fabs(maxWidth - SHRT_MAX) > 1) {
@ -33,6 +34,7 @@ void GCanvasContext::DrawTextWithLength(const char *text, int strLength, float x
Utf8ToUCS2 *lbData = new Utf8ToUCS2(text, strLength);
FillText(lbData->ucs2, lbData->ucs2len, x, y,
isStroke, scaleWidth);
@ -51,7 +53,6 @@ GCanvasContext::DoSetGlobalCompositeOperation(GCompositeOperation op, GComposite
SendVertexBufferToGPU();
GBlendOperationFuncs funcs = GCompositeOperationFuncs(op);
GBlendOperationFuncs alphaFuncs = GCompositeOperationFuncs(alphaOp);
glBlendFuncSeparate(funcs.source, funcs.destination,

View File

@ -97,9 +97,8 @@ void GFont::SetFtLibrary(FT_Library library) {
void GFont::DrawText(GCanvasContext *context, wchar_t text, float &x, float y,
GColorRGBA color, float sx, float sy, bool isStroke) {
bool needDrawShadow = context->NeedDrawShadow();
const GGlyph *glyph = GetOrLoadGlyph(context->mCurrentState->mFont, text, isStroke, sx, sy,
context->mCurrentState->mLineWidth,context->GetDevicePixelRatio());
bool needDrawShadow = context->NeedDrawShadow();
const GGlyph *glyph = GetOrLoadGlyph(context->mCurrentState->mFont, text, isStroke, sx, sy);
if (glyph != nullptr) {
DrawGlyph(context, glyph, x, y, sx, sy, color,needDrawShadow);
x += glyph->advanceX / sx;
@ -114,20 +113,21 @@ void GFont::DrawText(GCanvasContext *context, const wchar_t *text, float &x,
if (text == nullptr || wcslen(text) == 0) {
return;
}
bool needDrawShadow = context->NeedDrawShadow();
for (size_t i = 0; i < wcslen(text); ++i) {
const GGlyph *glyph = GetOrLoadGlyph(context->mCurrentState->mFont, text[i], isStroke, sx, sy,
context->mCurrentState->mLineWidth,context->GetDevicePixelRatio());
const GGlyph *glyph = GetOrLoadGlyph(context->mCurrentState->mFont, text[i], isStroke, sx, sy);
if (glyph != nullptr) {
DrawGlyph(context, glyph, x, y, sx, sy, color,needDrawShadow);
DrawGlyph(context, glyph, x, y, sx, sy, color, needDrawShadow);
x += glyph->advanceX / sx;
}
}
}
void GFont::DrawGlyph(GCanvasContext *context, const GGlyph *glyph, float x,
float y, float sx, float sy, GColorRGBA color,bool needDrawShadow) {
float y, float sx, float sy, GColorRGBA color,
bool needDrawShadow) {
context->SetTexture(glyph->texture->GetTextureID());
float x0 = x + (glyph->offsetX / sx);
float y0 = y - (glyph->offsetY / sy);
@ -139,9 +139,6 @@ void GFont::DrawGlyph(GCanvasContext *context, const GGlyph *glyph, float x,
float t1 = glyph->t1;
// LOG_E("DrawGlyph post: x0=%f, y0=%f, x=%f, y=%f", x0, y0, x, y);
// context->PushRectangleFormat(x0,
// y0, w, h, s0, t0, s1 - s0, t1 - t0, color,
// context->mCurrentState->mTransform, false, nullptr, true);
if (needDrawShadow)
{
std::vector<GVertex> vec;
@ -162,7 +159,6 @@ void GFont::DrawGlyph(GCanvasContext *context, const GGlyph *glyph, float x,
}
}
void GFont::SetFontCallback(
void *(*getFontCB)(const char *fontDefinition),
bool (*getFontImageCB)(void *font, wchar_t charcode, int &ftBitmapWidth,
@ -175,7 +171,7 @@ void GFont::SetFontCallback(
const GGlyph *GFont::GetOrLoadGlyph(gcanvas::GFontStyle* fontStyle, const wchar_t charCode, bool isStroke,
float sx, float sy,float lineWidth,float deviceRatio) {
float sx, float sy) {
std::string fontKey = GetGlyphKey(mFontFileName, fontStyle, sx, sy);
const GGlyph *glyph = mFontManager.mGlyphCache.GetGlyph(mFontFileName, charCode, fontKey, isStroke, false);
if (glyph != nullptr) {
@ -187,7 +183,7 @@ const GGlyph *GFont::GetOrLoadGlyph(gcanvas::GFontStyle* fontStyle, const wchar_
wchar_t buffer[2] = {0, 0};
buffer[0] = charCode;
LoadGlyphs(fontStyle, buffer, isStroke, sx, sy,lineWidth,deviceRatio);
LoadGlyphs(fontStyle, buffer, isStroke, sx, sy);
UpdateCurrentTextMetrics();
glyph = mFontManager.mGlyphCache.GetGlyph(mFontFileName, charCode, fontKey, isStroke, false);
@ -227,7 +223,7 @@ const GGlyph *GFont::GetOrLoadGlyph(gcanvas::GFontStyle* fontStyle, const wchar_
void GFont::LoadGlyphs(gcanvas::GFontStyle* fontStyle, const wchar_t *charcodes, bool isStroke,
float sx, float sy,float lineWidth,float deviceRatio) {
float sx, float sy) {
FT_Glyph ft_glyph = nullptr;
FT_GlyphSlot slot;
FT_Bitmap ft_bitmap;
@ -304,7 +300,7 @@ void GFont::LoadGlyphs(gcanvas::GFontStyle* fontStyle, const wchar_t *charcodes,
if (isStroke) {
if (ftStroker == nullptr) {
if (!LoadStroke(mFontFileName.data(), &ftStroker, sx, sy,lineWidth,deviceRatio)) {
if (!LoadStroke(mFontFileName.data(), &ftStroker, sx, sy)) {
return;
}
}
@ -451,7 +447,7 @@ bool GFont::PrepareLoadGlyph(float fontSize, float scaleX, float scaleY) {
}
bool GFont::LoadStroke(const char *filename, FT_Stroker *stroker, float sx, float sy,float lineWidth,float deviceRatio) {
bool GFont::LoadStroke(const char *filename, FT_Stroker *stroker, float sx, float sy) {
assert(filename);
if (mLibrary == nullptr) {
return false;

View File

@ -81,7 +81,7 @@ public:
const GGlyph *GetOrLoadGlyph(gcanvas::GFontStyle* fontStyle, const wchar_t charcode, bool isStroke,
float scaleX, float scaleY,float lineWidth=1.0,float deviceRatio=1.0);
float scaleX, float scaleY);
// deprecated
@ -107,28 +107,25 @@ public:
void SetFtLibrary(FT_Library libraryPtr);
private:
void DrawGlyph(GCanvasContext *context, const GGlyph *glyph, float x, float y,
void DrawGlyph(GCanvasContext *context, const GGlyph *glyph, float x, float y,
float scaleX, float scaleY, GColorRGBA color, bool needDrawShadow);
static void *(*getFontCallback)(const char *fontDefinition);
static void *(*getFontCallback)(const char *fontDefinition);
static bool (*getFontImageCallback)(void *font, wchar_t charCode,
int &ftBitmapWidth, int &ftBitmapHeight,
unsigned char *&bitmapBuffer, int &left,
int &top, float &advanceX,
float &advanceY);
static bool (*getFontImageCallback)(void *font, wchar_t charCode,
int &ftBitmapWidth, int &ftBitmapHeight,
unsigned char *&bitmapBuffer, int &left,
int &top, float &advanceX,
float &advanceY);
#ifdef GFONT_LOAD_BY_FREETYPE
void LoadGlyphs(gcanvas::GFontStyle* style, const wchar_t *charCodes, bool isStroke,
float scaleX, float scaleY,float lineWidth,float deviceRatio);
float scaleX, float scaleY);
#endif
bool LoadStroke(const char *filename, FT_Stroker *stroker, float scaleX, float scaleY,float lineWidth,float deviceRatio);
bool LoadStroke(const char *filename, FT_Stroker *stroker, float scaleX, float scaleY);
bool LoadFaceIfNot();

View File

@ -172,7 +172,6 @@ float *GFontManagerAndroid::PreMeasureTextHeight(const char *text, unsigned int
float descender = 0;
for (unsigned int i = 0; i < text_length; ++i) {
//todo fixme
auto glyph = fonts[i]->GetOrLoadGlyph(fontStyle, ucs[i], false, sx, sy);
if (glyph != nullptr) {
top = glyph->offsetY / sy;
@ -193,7 +192,7 @@ float *GFontManagerAndroid::PreMeasureTextHeight(const char *text, unsigned int
}
void GFontManagerAndroid::AdjustTextPenPoint(GCanvasContext *context, std::vector<GFont*>& font,
void GFontManagerAndroid::AdjustTextPenPoint(GCanvasContext *context, std::vector<GFont*> font,
const unsigned short *text, unsigned int textLength,
bool isStroke, float &x, float &y, float sx, float sy) {
gcanvas::GFontStyle *fontStyle = context->mCurrentState->mFont;
@ -203,8 +202,7 @@ void GFontManagerAndroid::AdjustTextPenPoint(GCanvasContext *context, std::vecto
auto left_x = x;
auto delta_x = 0.0f;
for (unsigned int i = 0; i < textLength; ++i) {
auto glyph = font[i]->GetOrLoadGlyph(fontStyle, text[i], isStroke, sx, sy,
context->mCurrentState->mLineWidth,context->GetDevicePixelRatio());
auto glyph = font[i]->GetOrLoadGlyph(fontStyle, text[i], isStroke, sx, sy);
if (glyph != nullptr) {
delta_x += glyph->advanceX / sx;
}
@ -219,8 +217,7 @@ void GFontManagerAndroid::AdjustTextPenPoint(GCanvasContext *context, std::vecto
GFont *font0 = font[0];
// update font metrics
const GGlyph* glyph = font0->GetOrLoadGlyph(fontStyle, text[0], isStroke, sx, sy,
context->mCurrentState->mLineWidth,context->GetDevicePixelRatio());
const GGlyph* glyph = font0->GetOrLoadGlyph(fontStyle, text[0], isStroke, sx, sy);
if (glyph == nullptr) { // fail
return;
}

View File

@ -58,7 +58,7 @@ private:
gcanvas::GFontStyle *fontStyle);
void AdjustTextPenPoint(GCanvasContext* context, std::vector<GFont *>& font,
void AdjustTextPenPoint(GCanvasContext* context, std::vector<GFont *> font,
const unsigned short *text,
unsigned int textLength,
bool isStroke,

View File

@ -97,7 +97,7 @@ bool GFrameBufferObject::InitFBO(int width, int height, GColorRGBA color, bool e
mFboTexture.SetFormat(GL_RGBA);
mFboTexture.CreateTexture(nullptr,errVec);
mFboTexture.Bind();
// printf("init fbo called and useMsaa is %d \n",useMsaa);
if (useMsaa)
{
glFramebufferTexture2DMultisampleEXTFunc(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFboTexture.GetTextureID(), 0, samples);
@ -152,12 +152,11 @@ bool GFrameBufferObject::InitFBO(int width, int height, GColorRGBA color, bool e
if (depthFormat == GL_DEPTH24_STENCIL8_OES)
{
// printf("the init fbo depthFormat is GL_DEPTH24_STENCIL8_OES \n");
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mFboStencil);
}else{
// printf("the init fbo depthFormat is not GL_DEPTH24_STENCIL8_OES \n");
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, mFboStencil);
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mFboStencil);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, mFboStencil);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)

View File

@ -17,14 +17,9 @@
#include FT_STROKER_H
#undef __FTERRORS_H__
#define FT_ERRORDEF(e, v, s) {e, s},
#define FT_ERROR_START_LIST {
#define FT_ERROR_END_LIST \
{ \
0, 0 \
} \
} \
;
#define FT_ERRORDEF(e, v, s) { e, s },
#define FT_ERROR_START_LIST {
#define FT_ERROR_END_LIST { 0, 0 } };
const struct
{
int code;
@ -35,91 +30,76 @@ const struct
#endif
namespace gcanvas
{
const char *getErrorMessage(FT_Error err)
{
#undef __FTERRORS_H__
#define FT_ERRORDEF(e, v, s) \
case e: \
return s;
#define FT_ERROR_START_LIST \
switch (err) \
{
#define FT_ERROR_END_LIST }
namespace gcanvas {
#include FT_ERRORS_H
return "(Unknown error)";
const char *getErrorMessage(FT_Error err) {
#undef __FTERRORS_H__
#define FT_ERRORDEF(e, v, s) case e: return s;
#define FT_ERROR_START_LIST switch (err) {
#define FT_ERROR_END_LIST }
#include FT_ERRORS_H
return "(Unknown error)";
}
/**
* init FT_Library
*/
bool GFT_InitLibrary(FT_Library * library)
{
if (library == nullptr)
{
bool GFT_InitLibrary(FT_Library *library) {
if (library == nullptr) {
return false;
}
FT_Error error = FT_Init_FreeType(library);
if (error)
{
if (error) {
LOG_E("GFT_InitLibrary:error,%s", getErrorMessage(error));
return false;
}
return true;
}
/**
* try load filename face, if not
*/
bool GFT_LoadFace(FT_Library library, FT_Face * face,
const char *filename, float width, float height)
{
if (library == nullptr)
{
printf("library is nullptr \n");
bool GFT_LoadFace(FT_Library library, FT_Face *face,
const char *filename, float width, float height) {
if (library == nullptr) {
return false;
}
size_t hres = 64;
FT_Matrix matrix = {(int)((1.0 / hres) * 0x10000L), (int)((0.0) * 0x10000L),
(int)((0.0) * 0x10000L), (int)((1.0) * 0x10000L)};
FT_Matrix matrix = {(int) ((1.0 / hres) * 0x10000L), (int) ((0.0) * 0x10000L),
(int) ((0.0) * 0x10000L), (int) ((1.0) * 0x10000L)};
FT_Error error;
// 如果走的是这个默认字体那么默认0采用的是日文JP(会导致【复/关】等不正常)强制改为走中文SC才可以
FT_Long faceIndex = 0;
if (strstr(filename, "NotoSansCJK-Regular.ttc"))
{
if (strstr(filename, "NotoSansCJK-Regular.ttc")) {
FT_Long i, num_faces;
FT_Face tmpFace;
FT_Open_Args args;
memset(&args, 0, sizeof(args));
args.flags = FT_OPEN_PATHNAME;
args.pathname = (FT_String *)filename;
args.pathname = (FT_String *) filename;
error = FT_Open_Face(library, &args, -1, &tmpFace);
if (error)
{
if (error) {
return false;
}
num_faces = tmpFace->num_faces;
for (i = 0; i < num_faces; i++)
{
for (i = 0; i < num_faces; i++) {
FT_Done_Face(tmpFace); //这里释放的是前一次(或循环外的第一次)
error = FT_Open_Face(library, &args, i, &tmpFace);
if (error)
{
if (error) {
return false;
}
else
{
} else {
FT_String *tmpFamily = tmpFace->family_name;
if (strstr(tmpFamily, "SC"))
{
if (strstr(tmpFamily, "SC")) {
faceIndex = i;
break;
}
@ -129,28 +109,22 @@ const struct
}
error = FT_New_Face(library, filename, faceIndex, face);
if (error)
{
printf("FT_New_Face error \n");
if (error) {
LOG_E("GFT_LoadFace %s fail: FT_New_Face error=%s", filename, getErrorMessage(error));
return false;
}
error = FT_Select_Charmap(*face, FT_ENCODING_UNICODE);
if (error)
{
printf("FT_Select_Charmap error \n");
if (error) {
LOG_E("GFT_LoadFace %s fail: FT_Select_Charmap error=%s", filename,
getErrorMessage(error));
return false;
}
bool flag;
if (width > 0 && height > 0)
{
if (width > 0 && height > 0) {
flag = GFT_SetFaceCharSize(*face, width, height);
if (!flag)
{
if (!flag) {
return false;
}
}
@ -159,20 +133,20 @@ const struct
return true;
}
bool GFT_SetFaceCharSize(FT_Face face, float newWidth, float newHeight)
{
bool GFT_SetFaceCharSize(FT_Face face, float newWidth, float newHeight) {
size_t hres = 64;
// FT_Matrix matrix = {(int) ((1.0 / hres) * 0x10000L), (int) ((0.0) * 0x10000L),
// (int) ((0.0) * 0x10000L), (int) ((1.0) * 0x10000L)};
FT_Error error = FT_Set_Char_Size(face, (int)(newWidth * 64), (int)(newHeight * 64), (FT_UInt)72 * hres, 72);
if (error)
{
FT_Error error = FT_Set_Char_Size(face, (int)(newWidth * 64), (int)(newHeight * 64), (FT_UInt) 72 * hres, 72);
if (error) {
return false;
}
return true;
}
/**
* @FIXME
* remove width/height parameter, we do no need size just for check charcode exist
@ -180,78 +154,69 @@ const struct
* this call is costly, use carefully
*/
bool GFT_IsCharInFontFile(FT_Library library, const wchar_t charCode,
const char *filename, float width, float height)
{
const char *filename, float width, float height) {
FT_Face face = nullptr;
bool exist = false;
if (GFT_LoadFace(library, &face, filename, width, height))
{
if (GFT_LoadFace(library, &face, filename, width, height)) {
exist = GFT_IsCharInFace(face, charCode);
}
else
{
} else {
// load face fail, ignore
}
GFT_DisposeFaceSafe(face);
return exist;
}
/**
* check charCode in FT_Face
*/
bool GFT_IsCharInFace(FT_Face face, const wchar_t charCode)
{
bool GFT_IsCharInFace(FT_Face face, const wchar_t charCode) {
bool exist = true;
if (face == nullptr)
{
if (face == nullptr) {
return false;
}
if (charCode == 0)
{
if (charCode == 0) {
return false;
}
FT_UInt glyphIndex = FT_Get_Char_Index(face, charCode);
if (glyphIndex == 0)
{
if (glyphIndex == 0) {
exist = false;
}
return exist;
}
void GFT_DisposeFaceSafe(FT_Face face)
{
if (face == nullptr)
{
void GFT_DisposeFaceSafe(FT_Face face) {
if (face == nullptr) {
return;
}
FT_Done_Face(face);
}
void GFT_DisposeLibrarySafe(FT_Library library)
{
if (library == nullptr)
{
void GFT_DisposeLibrarySafe(FT_Library library) {
if (library == nullptr) {
return;
}
FT_Done_FreeType(library);
}
void GFT_DisposeGlyphSafe(FT_Glyph glyph)
{
if (glyph == nullptr)
{
void GFT_DisposeGlyphSafe(FT_Glyph glyph) {
if (glyph == nullptr) {
return;
}
FT_Done_Glyph(glyph);
}
void GFT_DisposeStrokeSafe(FT_Stroker stroker)
{
if (stroker == nullptr)
{
void GFT_DisposeStrokeSafe(FT_Stroker stroker) {
if (stroker == nullptr) {
return;
}
FT_Stroker_Done(stroker);
}
}

View File

@ -14,8 +14,9 @@
#include "GFontStyle.h"
#include "GCanvas2dContext.h"
#import <pthread.h>
#define GCV_FONT_GLYPH_PADDING 0
#define GCV_FONT_GLYPH_PADDING 2
#pragma mark - GFontLayout
@implementation GFontLayout
@ -49,7 +50,7 @@
NSString *_key;
}
static NSMutableDictionary *staticFontInstaceDict;
pthread_mutex_t fontMutex = PTHREAD_MUTEX_INITIALIZER;
+ (NSMutableDictionary*)staticFontInstaceDict
{
static NSMutableDictionary *fontInstanceDict;
@ -62,18 +63,25 @@ static NSMutableDictionary *staticFontInstaceDict;
+ (instancetype)createGCFontWithKey:(NSString*)key
{
GCVFont *gcvFont = [[GCVFont alloc] initWithKey:key];
pthread_mutex_lock(&fontMutex);
self.staticFontInstaceDict[key] = gcvFont;
pthread_mutex_unlock(&fontMutex);
return gcvFont;
}
+ (GCVFont *)getGCVFontWithKey:(NSString*)key
{
return self.staticFontInstaceDict[key];
pthread_mutex_lock(&fontMutex);
GCVFont *font = self.staticFontInstaceDict[key];
pthread_mutex_unlock(&fontMutex);
return font;
}
+ (void)removeGCVFontWithKey:(NSString*)key
{
return [self.staticFontInstaceDict removeObjectForKey:key];
pthread_mutex_lock(&fontMutex);
[self.staticFontInstaceDict removeObjectForKey:key];
pthread_mutex_unlock(&fontMutex);
}
- (instancetype)initWithKey:(NSString *)key
@ -251,6 +259,7 @@ static NSMutableDictionary *staticFontInstaceDict;
context:(GCanvasContext *)context
{
bool needDrawShadow = context->NeedDrawShadow();
int offsetX = 0;
GColorRGBA color = self.isStroke ? BlendStrokeColor(context) : BlendFillColor(context);

View File

@ -7,6 +7,8 @@
* the LICENSE file in the root directory of this source tree.
*/
#include "Log.h"
#include <vector>
//namespace gcanvas {

View File

@ -12,9 +12,8 @@
#if defined(__ANDROID__)
#include <android/log.h>
#endif
#include <vector>
#include <stdarg.h>
#include <string>
#include <iostream>
#include "export.h"

View File

@ -162,7 +162,7 @@ namespace gcanvas {
} else if (strcmp(str, "destination-over") == 0) {
op = GCompositeOperation::COMPOSITE_OP_DESTINATION_OVER;
} else if (strcmp(str, "destination-atop") == 0) {
op = GCompositeOperation::COMPOSITE_OP_SOURCE_ATOP;
op = GCompositeOperation::COMPOSITE_OP_DESTINATION_ATOP;
} else if (strcmp(str, "destination-in") == 0) {
op = GCompositeOperation::COMPOSITE_OP_DESTINATION_IN;
} else if (strcmp(str, "destination-out") == 0) {
@ -173,6 +173,8 @@ namespace gcanvas {
op = GCompositeOperation::COMPOSITE_OP_XOR;
} else if (strcmp(str, "copy") == 0) {
op = GCompositeOperation::COMPOSITE_OP_COPY;
} else if (strcmp(str, "clear") == 0) {
op = GCompositeOperation::COMPOSITE_OP_CLEAR;
} else {
op = GCompositeOperation::COMPOSITE_OP_NONE;
}
@ -216,6 +218,9 @@ namespace gcanvas {
case COMPOSITE_OP_XOR:
result = "xor";
break;
case COMPOSITE_OP_CLEAR:
result = "clear";
break;
}
return result;
}

View File

@ -9,7 +9,6 @@
#include "Value.h"
#include <iomanip>
#include <sstream>
#include <string.h>
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.192092896e-07F

View File

@ -23,6 +23,9 @@
namespace gcanvas
{
typedef void (*GCommandWebGLFunc)(GCommandBuffer& , GDecodeRes& );
//#define WEBGL_FUNC_ARRAY_ASSIGN(NAME) \
//mWebGLFuncs[GWEBGL_FUNC_##NAME] = std::bind(&GCommandDecoderWebGL::WebGL_##NAME, this, std::placeholders::_1, std::placeholders::_2);
@ -394,7 +397,7 @@ void GCommandDecoderWebGL::InitCommands()
bool GCommandDecoderWebGL::Decode(GCommandBuffer& buffer, GDecodeRes& res)
{
static GCommandFuncPtr mWebGLFuncs[GWEBGL_FUNC_COUNT] = {
static GCommandWebGLFunc mWebGLFuncs[GWEBGL_FUNC_COUNT] = {
nullptr,
&GCommandDecoderWebGL::WebGL_activeTexture,
&GCommandDecoderWebGL::WebGL_attachShader,
@ -616,7 +619,7 @@ bool GCommandDecoderWebGL::Decode(GCommandBuffer& buffer, GDecodeRes& res)
return false;
}
GCommandFuncPtr func = mWebGLFuncs[funcId];
GCommandWebGLFunc func = mWebGLFuncs[funcId];
if( !func )
{
LOG_E("[Error] Can't find WebGL API ID::%d", funcId);
@ -1856,7 +1859,7 @@ void GCommandDecoderWebGL::WebGL_texImage2D(GCommandBuffer& buffer, GDecodeRes&
if( !ret || !uID ) return;
//fetch pixels
WebGL::JSBindingPixels gPixels;
JSBindingPixels gPixels;
mRenderContext->FetchPixels(*uID, 0, &gPixels);
short width = gPixels.width;
@ -2027,7 +2030,7 @@ void GCommandDecoderWebGL::WebGL_texSubImage2D(GCommandBuffer& buffer, GDecodeRe
if( !ret || !uID ) return;
//fetch pixels
WebGL::JSBindingPixels gPixels;
JSBindingPixels gPixels;
mRenderContext->FetchPixels(*uID, 0, &gPixels);
short width = gPixels.width;

View File

@ -181,7 +181,7 @@ class GCommandDecoderWebGL : public GCommandDecoder
public:
API_EXPORT GCommandDecoderWebGL(WebGL::GWebGLRenderContext* renderContext);
API_EXPORT ~GCommandDecoderWebGL();
API_EXPORT virtual ~GCommandDecoderWebGL();
virtual void InitCommands();
inline virtual bool IsSyncCommand(uint32_t cmdId){

View File

@ -18,18 +18,6 @@ namespace gcanvas {
namespace WebGL {
JSBindingPixels::JSBindingPixels():
textureId(0), width(0), height(0), pixels(nullptr)
{
}
JSBindingPixels::~JSBindingPixels()
{
}
GWebGLRenderContext::GWebGLRenderContext(std::string contextId)
: mContextId(contextId), mDrawCall(0),mNeed_draw(false),
mUnpackFlipY_WebGL(false), mPremultiplyAlpha_WebGL(false)

View File

@ -19,6 +19,7 @@
#include <vector>
#include "../export.h"
#include "GGL.h"
#include "GCommandTypes.hpp"
namespace gcanvas
@ -27,35 +28,6 @@ namespace gcanvas
namespace WebGL
{
class JSBindingPixels
{
public:
API_EXPORT JSBindingPixels();
API_EXPORT ~JSBindingPixels();
JSBindingPixels(JSBindingPixels &&v)
{
textureId = v.textureId;
pixels = v.pixels;
width = v.width;
height = v.height;
v.textureId = 0;
v.pixels = nullptr;
v.width = 0;
v.height = 0;
}
uint32_t textureId;
uint8_t* pixels;
short width;
short height;
};
//Fectch pixels form JSBinding instance with instanceID
using FetchPixelsFunc = std::function< void (void*obj, uint64_t, JSBindingPixels*) >;
//bindframebuffer null
using BindFramebufferNullFunc = std::function< void(void*obj) >;
//glResource

View File

@ -16,6 +16,7 @@
#import "GCanvasObject.h"
#import "GCanvasPlugin.h"
#import "GCVCommon.h"
#import "GCVFont.h"
#import "GCVLog.h"

View File

@ -87,6 +87,22 @@
A284A306234348880029BBCA /* GCanvasSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = A284A27E234348880029BBCA /* GCanvasSDK.h */; };
A284A307234348880029BBCA /* GCanvasObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A284A27F234348880029BBCA /* GCanvasObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
A284A308234348880029BBCA /* GCVCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = A284A280234348880029BBCA /* GCVCommon.h */; settings = {ATTRIBUTES = (Public, ); }; };
A2A8990A25E4B463008C90F2 /* GCommandTypes.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A2A898F825E4B463008C90F2 /* GCommandTypes.hpp */; };
A2A8990B25E4B463008C90F2 /* GCommandDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A898F925E4B463008C90F2 /* GCommandDecoder.cpp */; };
A2A8990C25E4B463008C90F2 /* GCommandBuffer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A2A898FA25E4B463008C90F2 /* GCommandBuffer.hpp */; };
A2A8990D25E4B463008C90F2 /* GCommandTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A898FB25E4B463008C90F2 /* GCommandTypes.cpp */; };
A2A8990E25E4B463008C90F2 /* GCommandDecoder.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A2A898FC25E4B463008C90F2 /* GCommandDecoder.hpp */; };
A2A8990F25E4B463008C90F2 /* GCommandBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A898FD25E4B463008C90F2 /* GCommandBuffer.cpp */; };
A2A8991025E4B463008C90F2 /* GWebGLRenderContextInner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A898FF25E4B463008C90F2 /* GWebGLRenderContextInner.cpp */; };
A2A8991125E4B463008C90F2 /* GCommandDecoderWebGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A8990025E4B463008C90F2 /* GCommandDecoderWebGL.cpp */; };
A2A8991225E4B463008C90F2 /* GWebGLRenderContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A8990125E4B463008C90F2 /* GWebGLRenderContext.cpp */; };
A2A8991325E4B463008C90F2 /* GWebGLRenderContext.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A2A8990225E4B463008C90F2 /* GWebGLRenderContext.hpp */; };
A2A8991425E4B463008C90F2 /* GWebGLRenderContextInner.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A2A8990325E4B463008C90F2 /* GWebGLRenderContextInner.hpp */; };
A2A8991525E4B463008C90F2 /* GCommandDecoderWebGL.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A2A8990425E4B463008C90F2 /* GCommandDecoderWebGL.hpp */; };
A2A8991625E4B463008C90F2 /* GContext2DRenderContext.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A2A8990625E4B463008C90F2 /* GContext2DRenderContext.hpp */; };
A2A8991725E4B463008C90F2 /* GCommandDecoder2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A8990725E4B463008C90F2 /* GCommandDecoder2D.cpp */; };
A2A8991825E4B463008C90F2 /* GCommandDecoder2D.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A2A8990825E4B463008C90F2 /* GCommandDecoder2D.hpp */; };
A2A8991925E4B463008C90F2 /* GContext2DRenderContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2A8990925E4B463008C90F2 /* GContext2DRenderContext.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -171,6 +187,22 @@
A284A27E234348880029BBCA /* GCanvasSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCanvasSDK.h; sourceTree = "<group>"; };
A284A27F234348880029BBCA /* GCanvasObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCanvasObject.h; sourceTree = "<group>"; };
A284A280234348880029BBCA /* GCVCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCVCommon.h; sourceTree = "<group>"; };
A2A898F825E4B463008C90F2 /* GCommandTypes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GCommandTypes.hpp; sourceTree = "<group>"; };
A2A898F925E4B463008C90F2 /* GCommandDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCommandDecoder.cpp; sourceTree = "<group>"; };
A2A898FA25E4B463008C90F2 /* GCommandBuffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GCommandBuffer.hpp; sourceTree = "<group>"; };
A2A898FB25E4B463008C90F2 /* GCommandTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCommandTypes.cpp; sourceTree = "<group>"; };
A2A898FC25E4B463008C90F2 /* GCommandDecoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GCommandDecoder.hpp; sourceTree = "<group>"; };
A2A898FD25E4B463008C90F2 /* GCommandBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCommandBuffer.cpp; sourceTree = "<group>"; };
A2A898FF25E4B463008C90F2 /* GWebGLRenderContextInner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GWebGLRenderContextInner.cpp; sourceTree = "<group>"; };
A2A8990025E4B463008C90F2 /* GCommandDecoderWebGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCommandDecoderWebGL.cpp; sourceTree = "<group>"; };
A2A8990125E4B463008C90F2 /* GWebGLRenderContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GWebGLRenderContext.cpp; sourceTree = "<group>"; };
A2A8990225E4B463008C90F2 /* GWebGLRenderContext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GWebGLRenderContext.hpp; sourceTree = "<group>"; };
A2A8990325E4B463008C90F2 /* GWebGLRenderContextInner.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GWebGLRenderContextInner.hpp; sourceTree = "<group>"; };
A2A8990425E4B463008C90F2 /* GCommandDecoderWebGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GCommandDecoderWebGL.hpp; sourceTree = "<group>"; };
A2A8990625E4B463008C90F2 /* GContext2DRenderContext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GContext2DRenderContext.hpp; sourceTree = "<group>"; };
A2A8990725E4B463008C90F2 /* GCommandDecoder2D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCommandDecoder2D.cpp; sourceTree = "<group>"; };
A2A8990825E4B463008C90F2 /* GCommandDecoder2D.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GCommandDecoder2D.hpp; sourceTree = "<group>"; };
A2A8990925E4B463008C90F2 /* GContext2DRenderContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GContext2DRenderContext.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -268,6 +300,9 @@
A231B1E7235064DA00466BE3 /* GCanvasWeex.hpp */,
A25FB0EB2343491500EF73E5 /* GCanvasManager.cpp */,
A25FB0DA2343491500EF73E5 /* GCanvasManager.h */,
A2A8990525E4B463008C90F2 /* 2d */,
A2A898F725E4B463008C90F2 /* commandbuffer */,
A2A898FE25E4B463008C90F2 /* webgl */,
A25FB0C92343491500EF73E5 /* platform */,
A25FB0DB2343491500EF73E5 /* support */,
);
@ -364,6 +399,43 @@
path = ../BridgeModule;
sourceTree = "<group>";
};
A2A898F725E4B463008C90F2 /* commandbuffer */ = {
isa = PBXGroup;
children = (
A2A898F825E4B463008C90F2 /* GCommandTypes.hpp */,
A2A898F925E4B463008C90F2 /* GCommandDecoder.cpp */,
A2A898FA25E4B463008C90F2 /* GCommandBuffer.hpp */,
A2A898FB25E4B463008C90F2 /* GCommandTypes.cpp */,
A2A898FC25E4B463008C90F2 /* GCommandDecoder.hpp */,
A2A898FD25E4B463008C90F2 /* GCommandBuffer.cpp */,
);
path = commandbuffer;
sourceTree = "<group>";
};
A2A898FE25E4B463008C90F2 /* webgl */ = {
isa = PBXGroup;
children = (
A2A898FF25E4B463008C90F2 /* GWebGLRenderContextInner.cpp */,
A2A8990025E4B463008C90F2 /* GCommandDecoderWebGL.cpp */,
A2A8990125E4B463008C90F2 /* GWebGLRenderContext.cpp */,
A2A8990225E4B463008C90F2 /* GWebGLRenderContext.hpp */,
A2A8990325E4B463008C90F2 /* GWebGLRenderContextInner.hpp */,
A2A8990425E4B463008C90F2 /* GCommandDecoderWebGL.hpp */,
);
path = webgl;
sourceTree = "<group>";
};
A2A8990525E4B463008C90F2 /* 2d */ = {
isa = PBXGroup;
children = (
A2A8990625E4B463008C90F2 /* GContext2DRenderContext.hpp */,
A2A8990725E4B463008C90F2 /* GCommandDecoder2D.cpp */,
A2A8990825E4B463008C90F2 /* GCommandDecoder2D.hpp */,
A2A8990925E4B463008C90F2 /* GContext2DRenderContext.cpp */,
);
path = 2d;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -373,14 +445,18 @@
files = (
A284A303234348880029BBCA /* GCVLog.h in Headers */,
A25FB21D2343491700EF73E5 /* GCVFont.h in Headers */,
A2A8990C25E4B463008C90F2 /* GCommandBuffer.hpp in Headers */,
A284A308234348880029BBCA /* GCVCommon.h in Headers */,
A284A2FF234348880029BBCA /* GCanvasPlugin.h in Headers */,
A284A307234348880029BBCA /* GCanvasObject.h in Headers */,
A24156E424AC628B00405D95 /* GGL.h in Headers */,
A2A8991425E4B463008C90F2 /* GWebGLRenderContextInner.hpp in Headers */,
A2A8991625E4B463008C90F2 /* GContext2DRenderContext.hpp in Headers */,
A284A301234348880029BBCA /* GCanvasModule.h in Headers */,
A284A2FD234348880029BBCA /* GCanvasModuleProtocol.h in Headers */,
A284A304234348880029BBCA /* GCanvasViewProtocol.h in Headers */,
A284A306234348880029BBCA /* GCanvasSDK.h in Headers */,
A2A8991825E4B463008C90F2 /* GCommandDecoder2D.hpp in Headers */,
A25FB2102343491700EF73E5 /* GStrSeparator.h in Headers */,
A25FB1F62343491700EF73E5 /* GConvert.h in Headers */,
A25FB2142343491700EF73E5 /* GTreemap.h in Headers */,
@ -389,6 +465,7 @@
A25FB2342343491700EF73E5 /* Log.h in Headers */,
A24156E524AC628B00405D95 /* GTexture.h in Headers */,
A25FB1F92343491700EF73E5 /* GFontStyle.h in Headers */,
A2A8991525E4B463008C90F2 /* GCommandDecoderWebGL.hpp in Headers */,
A24156FB24AC628B00405D95 /* GPathStroker.h in Headers */,
A25FB21B2343491700EF73E5 /* GCanvas.hpp in Headers */,
A24156EA24AC628B00405D95 /* GShader.h in Headers */,
@ -399,10 +476,13 @@
A25FB20E2343491700EF73E5 /* GWebglContext.h in Headers */,
A25FB2362343491700EF73E5 /* DynArray.h in Headers */,
A25FB2392343491700EF73E5 /* Encode.h in Headers */,
A2A8990E25E4B463008C90F2 /* GCommandDecoder.hpp in Headers */,
A2A8990A25E4B463008C90F2 /* GCommandTypes.hpp in Headers */,
A25FB2172343491700EF73E5 /* GTextDefine.h in Headers */,
A25FB1F82343491700EF73E5 /* GFillStyle.h in Headers */,
A25FB1F22343491700EF73E5 /* GTransform.h in Headers */,
A25FB2132343491700EF73E5 /* GCanvas2dContext.h in Headers */,
A2A8991325E4B463008C90F2 /* GWebGLRenderContext.hpp in Headers */,
A25FB2372343491700EF73E5 /* Util.h in Headers */,
A25FB2152343491700EF73E5 /* GCanvasState.h in Headers */,
A24156EB24AC628B00405D95 /* GShaderManager.h in Headers */,
@ -495,9 +575,13 @@
A24156F524AC628B00405D95 /* GLUtil.cpp in Sources */,
A25FB2382343491700EF73E5 /* Encode.cpp in Sources */,
A25FB23C2343491700EF73E5 /* GCanvas.cpp in Sources */,
A2A8990F25E4B463008C90F2 /* GCommandBuffer.cpp in Sources */,
A2A8991125E4B463008C90F2 /* GCommandDecoderWebGL.cpp in Sources */,
A24156FA24AC628B00405D95 /* GPathStroker.cpp in Sources */,
A2A8991025E4B463008C90F2 /* GWebGLRenderContextInner.cpp in Sources */,
A25FB1F12343491700EF73E5 /* GFontStyle.cpp in Sources */,
A25FB21F2343491700EF73E5 /* GCVFont.mm in Sources */,
A2A8990B25E4B463008C90F2 /* GCommandDecoder.cpp in Sources */,
A25FB2042343491700EF73E5 /* GCanvas2dContext.cpp in Sources */,
A25FB2112343491700EF73E5 /* GWebglContext.cpp in Sources */,
A25FB2002343491700EF73E5 /* GTreemap.cpp in Sources */,
@ -511,13 +595,17 @@
A25FB2162343491700EF73E5 /* GGlyphCache.cpp in Sources */,
A24156FF24AC62C100405D95 /* GFontManagerIOS.mm in Sources */,
A284A305234348880029BBCA /* GCanvasPlugin.mm in Sources */,
A2A8991925E4B463008C90F2 /* GContext2DRenderContext.cpp in Sources */,
A2A8990D25E4B463008C90F2 /* GCommandTypes.cpp in Sources */,
A25FB1F32343491700EF73E5 /* GStrSeparator.cpp in Sources */,
A2A8991225E4B463008C90F2 /* GWebGLRenderContext.cpp in Sources */,
A231B1E8235064DA00466BE3 /* GCanvasWeex.cpp in Sources */,
A24156F624AC628B00405D95 /* GTexture.cpp in Sources */,
A24156ED24AC628B00405D95 /* GShader.cpp in Sources */,
A25FB22C2343491700EF73E5 /* Log.cpp in Sources */,
A284A2FE234348880029BBCA /* GCVCommon.m in Sources */,
A25FB22D2343491700EF73E5 /* Util.cpp in Sources */,
A2A8991725E4B463008C90F2 /* GCommandDecoder2D.cpp in Sources */,
A25FB1FF2343491700EF73E5 /* GCanvasState.cpp in Sources */,
A284A2FB234348880029BBCA /* GCVLog.m in Sources */,
A284A2FC234348880029BBCA /* GCanvasModule.m in Sources */,