mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +00:00
193 lines
4.8 KiB
C++
193 lines
4.8 KiB
C++
/*
|
|
* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*/
|
|
#ifndef _TVG_RENDER_COMMON_H_
|
|
#define _TVG_RENDER_COMMON_H_
|
|
|
|
namespace tvg
|
|
{
|
|
|
|
struct Surface
|
|
{
|
|
//TODO: Union for multiple types
|
|
uint32_t* buffer;
|
|
uint32_t stride;
|
|
uint32_t w, h;
|
|
};
|
|
|
|
enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, All = 32};
|
|
|
|
struct RenderTransform
|
|
{
|
|
//3x3 Matrix Elements
|
|
float e11, e12, e13;
|
|
float e21, e22, e23;
|
|
float e31, e32, e33;
|
|
|
|
float x = 0.0f;
|
|
float y = 0.0f;
|
|
float degree = 0.0f; //rotation degree
|
|
float factor = 1.0f; //scale factor
|
|
|
|
bool update()
|
|
{
|
|
constexpr auto PI = 3.141592f;
|
|
|
|
//Init Status
|
|
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON &&
|
|
fabsf(degree) <= FLT_EPSILON && fabsf(factor - 1) <= FLT_EPSILON) {
|
|
return false;
|
|
}
|
|
|
|
//identity
|
|
e11 = 1.0f;
|
|
e12 = 0.0f;
|
|
e13 = 0.0f;
|
|
e21 = 0.0f;
|
|
e22 = 1.0f;
|
|
e23 = 0.0f;
|
|
e31 = 0.0f;
|
|
e32 = 0.0f;
|
|
e33 = 1.0f;
|
|
|
|
//scale
|
|
e11 *= factor;
|
|
e22 *= factor;
|
|
e33 *= factor;
|
|
|
|
//rotation
|
|
if (fabsf(degree) > FLT_EPSILON) {
|
|
auto radian = degree / 180.0f * PI;
|
|
auto cosVal = cosf(radian);
|
|
auto sinVal = sinf(radian);
|
|
|
|
auto t11 = e11 * cosVal + e12 * sinVal;
|
|
auto t12 = e11 * -sinVal + e12 * cosVal;
|
|
auto t21 = e21 * cosVal + e22 * sinVal;
|
|
auto t22 = e21 * -sinVal + e22 * cosVal;
|
|
auto t31 = e31 * cosVal + e32 * sinVal;
|
|
auto t32 = e31 * -sinVal + e32 * cosVal;
|
|
|
|
e11 = t11;
|
|
e12 = t12;
|
|
e21 = t21;
|
|
e22 = t22;
|
|
e31 = t31;
|
|
e32 = t32;
|
|
}
|
|
|
|
e31 += x;
|
|
e32 += y;
|
|
|
|
return true;
|
|
}
|
|
|
|
RenderTransform()
|
|
{
|
|
}
|
|
|
|
RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs)
|
|
{
|
|
assert(lhs && rhs);
|
|
|
|
auto dx = rhs->x * lhs->factor;
|
|
auto dy = rhs->y * lhs->factor;
|
|
auto tx = dx * lhs->e11 + dy * lhs->e12 + lhs->e13;
|
|
auto ty = dx * lhs->e21 + dy * lhs->e22 + lhs->e23;
|
|
|
|
x = lhs->x + tx;
|
|
y = lhs->y + ty;
|
|
degree = lhs->degree + rhs->degree;
|
|
factor = lhs->factor * rhs->factor;
|
|
|
|
update();
|
|
}
|
|
};
|
|
|
|
|
|
class RenderMethod
|
|
{
|
|
public:
|
|
virtual ~RenderMethod() {}
|
|
virtual void* prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags) = 0;
|
|
virtual bool dispose(const Shape& shape, void *data) = 0;
|
|
virtual bool render(const Shape& shape, void *data) = 0;
|
|
virtual bool clear() = 0;
|
|
virtual uint32_t ref() = 0;
|
|
virtual uint32_t unref() = 0;
|
|
};
|
|
|
|
struct RenderInitializer
|
|
{
|
|
RenderMethod* pInst = nullptr;
|
|
uint32_t refCnt = 0;
|
|
bool initialized = false;
|
|
|
|
static bool init(RenderInitializer& renderInit, RenderMethod* engine)
|
|
{
|
|
assert(engine);
|
|
if (renderInit.pInst || renderInit.refCnt > 0) return false;
|
|
renderInit.pInst = engine;
|
|
renderInit.refCnt = 0;
|
|
renderInit.initialized = true;
|
|
return true;
|
|
}
|
|
|
|
static bool term(RenderInitializer& renderInit)
|
|
{
|
|
if (!renderInit.pInst || !renderInit.initialized) return false;
|
|
|
|
renderInit.initialized = false;
|
|
|
|
//Still it's refered....
|
|
if (renderInit.refCnt > 0) return true;
|
|
delete(renderInit.pInst);
|
|
renderInit.pInst = nullptr;
|
|
|
|
return true;
|
|
}
|
|
|
|
static uint32_t unref(RenderInitializer& renderInit)
|
|
{
|
|
assert(renderInit.refCnt > 0);
|
|
--renderInit.refCnt;
|
|
|
|
//engine has been requested to termination
|
|
if (!renderInit.initialized && renderInit.refCnt == 0) {
|
|
if (renderInit.pInst) {
|
|
delete(renderInit.pInst);
|
|
renderInit.pInst = nullptr;
|
|
}
|
|
}
|
|
return renderInit.refCnt;
|
|
}
|
|
|
|
static RenderMethod* inst(RenderInitializer& renderInit)
|
|
{
|
|
assert(renderInit.pInst);
|
|
return renderInit.pInst;
|
|
}
|
|
|
|
static uint32_t ref(RenderInitializer& renderInit)
|
|
{
|
|
return ++renderInit.refCnt;
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif //_TVG_RENDER_COMMON_H_
|