mirror of
https://github.com/alibaba/GCanvas.git
synced 2026-02-01 14:33:10 +00:00
feat: merge from new version
This commit is contained in:
parent
d593edbc7f
commit
64d7d080cb
@ -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
|
||||
)
|
||||
|
||||
|
||||
|
||||
776
core/src/2d/GCommandDecoder2D.cpp
Normal file
776
core/src/2d/GCommandDecoder2D.cpp
Normal 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
|
||||
174
core/src/2d/GCommandDecoder2D.hpp
Normal file
174
core/src/2d/GCommandDecoder2D.hpp
Normal 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
|
||||
49
core/src/2d/GContext2DRenderContext.cpp
Normal file
49
core/src/2d/GContext2DRenderContext.cpp
Normal 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
|
||||
62
core/src/2d/GContext2DRenderContext.hpp
Normal file
62
core/src/2d/GContext2DRenderContext.hpp
Normal 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
|
||||
@ -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:
|
||||
|
||||
27
core/src/commandbuffer/GCommandTypes.cpp
Normal file
27
core/src/commandbuffer/GCommandTypes.cpp
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
158
core/src/commandbuffer/GCommandTypes.hpp
Normal file
158
core/src/commandbuffer/GCommandTypes.hpp
Normal 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 */
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -123,6 +123,7 @@ void GCanvasState::ClearStyle() {
|
||||
delete mFillStyle;
|
||||
mFillStyle = nullptr;
|
||||
}
|
||||
|
||||
if (mStrokeStyle != nullptr) {
|
||||
delete mStrokeStyle;
|
||||
mStrokeStyle = nullptr;
|
||||
|
||||
@ -53,6 +53,8 @@ public:
|
||||
|
||||
GColorRGBA mStrokeColor;
|
||||
GFillStyle *mStrokeStyle;
|
||||
|
||||
GFillStyle *mCurrentFillStyle;
|
||||
|
||||
GColorRGBA mShadowColor;
|
||||
float mShadowBlur;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
|
||||
class GCanvasContext;
|
||||
|
||||
#define FontTextureWidth 2048
|
||||
#define FontTextureHeight 2048
|
||||
#define FontTextureWidth 1024
|
||||
#define FontTextureHeight 1024
|
||||
|
||||
namespace gcanvas
|
||||
{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -118,6 +118,7 @@ public:
|
||||
|
||||
void SetHasTexture(bool value)
|
||||
{
|
||||
|
||||
if (mHasTextureFlag != value)
|
||||
{
|
||||
mHasTextureFlag = value;
|
||||
|
||||
@ -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\
|
||||
}"
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -38,7 +38,7 @@ struct GPathCmd {
|
||||
|
||||
~GPathCmd() {
|
||||
if (data != nullptr) {
|
||||
free (data);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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变换
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
* the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
#include "Log.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
//namespace gcanvas {
|
||||
|
||||
@ -12,9 +12,8 @@
|
||||
#if defined(__ANDROID__)
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "Value.h"
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef FLT_EPSILON
|
||||
#define FLT_EPSILON 1.192092896e-07F
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#import "GCanvasObject.h"
|
||||
#import "GCanvasPlugin.h"
|
||||
#import "GCVCommon.h"
|
||||
#import "GCVFont.h"
|
||||
#import "GCVLog.h"
|
||||
|
||||
|
||||
|
||||
@ -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 */,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user