thorvg/src/lib/tvgShapePath.h
Hermet Park 682bc25298 common shape: revise scale/rotate approach.
Come to think of it, this optimized method is not so useful,
it could just bring the user misunderstanding and
not to efficient as I expected in the most cases.

So, changed policy for transformation behaviors.
it keeps the properties as others but leaves it to the backend implementation.

Plus, this change contains the correct RenderUpdateFlag.
You can refer the flag in the backend to figure out which kinds of properites has been updated

Change-Id: Ibe0494712598a8161950b9ae2e22ac45bed1c47b
2020-05-03 15:03:29 +09:00

139 lines
3.9 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_SHAPE_PATH_CPP_
#define _TVG_SHAPE_PATH_CPP_
#include "tvgCommon.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
struct ShapePath
{
PathCommand* cmds = nullptr;
size_t cmdCnt = 0;
size_t reservedCmdCnt = 0;
Point *pts = nullptr;
size_t ptsCnt = 0;
size_t reservedPtsCnt = 0;
~ShapePath()
{
if (cmds) delete(cmds);
if (pts) delete(pts);
}
void reserveCmd(size_t cmdCnt)
{
if (cmdCnt <= reservedCmdCnt) return;
reservedCmdCnt = cmdCnt;
cmds = static_cast<PathCommand*>(realloc(cmds, sizeof(PathCommand) * reservedCmdCnt));
assert(cmds);
}
void reservePts(size_t ptsCnt)
{
if (ptsCnt <= reservedPtsCnt) return;
reservedPtsCnt = ptsCnt;
pts = static_cast<Point*>(realloc(pts, sizeof(Point) * reservedPtsCnt));
assert(pts);
}
void grow(size_t cmdCnt, size_t ptsCnt)
{
reserveCmd(this->cmdCnt + cmdCnt);
reservePts(this->ptsCnt + ptsCnt);
}
void reset()
{
cmdCnt = 0;
ptsCnt = 0;
}
void append(const PathCommand* cmds, size_t cmdCnt, const Point* pts, size_t ptsCnt)
{
memcpy(this->cmds + this->cmdCnt, cmds, sizeof(PathCommand) * cmdCnt);
memcpy(this->pts + this->ptsCnt, pts, sizeof(Point) * ptsCnt);
this->cmdCnt += cmdCnt;
this->ptsCnt += ptsCnt;
}
void moveTo(float x, float y)
{
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2);
cmds[cmdCnt++] = PathCommand::MoveTo;
pts[ptsCnt++] = {x, y};
}
void lineTo(float x, float y)
{
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2);
cmds[cmdCnt++] = PathCommand::LineTo;
pts[ptsCnt++] = {x, y};
}
void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y)
{
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
if (ptsCnt + 3 > reservedPtsCnt) reservePts((ptsCnt + 3) * 2);
cmds[cmdCnt++] = PathCommand::CubicTo;
pts[ptsCnt++] = {cx1, cy1};
pts[ptsCnt++] = {cx2, cy2};
pts[ptsCnt++] = {x, y};
}
void close()
{
if (cmdCnt > 0 && cmds[cmdCnt - 1] == PathCommand::Close) return;
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
cmds[cmdCnt++] = PathCommand::Close;
}
bool bounds(float& x, float& y, float& w, float& h)
{
if (ptsCnt == 0) return false;
Point min = { pts[0].x, pts[0].y };
Point max = { pts[0].x, pts[0].y };
for(size_t i = 1; i < ptsCnt; ++i) {
if (pts[i].x < min.x) min.x = pts[i].x;
if (pts[i].y < min.y) min.y = pts[i].y;
if (pts[i].x > max.x) max.x = pts[i].x;
if (pts[i].y > max.y) max.y = pts[i].y;
}
x = min.x;
y = min.y;
w = max.x - min.x;
h = max.y - min.y;
return true;
}
};
#endif //_TVG_SHAPE_PATH_CPP_