mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
implement rle raster.
Change-Id: Ie21dfbf0ff1aed43bfa750eeef3b8c033a986416
This commit is contained in:
parent
f9fcd58744
commit
70c9860d8f
10 changed files with 461 additions and 34 deletions
|
@ -29,7 +29,7 @@ struct GlShape
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void* GlRaster::prepare(const ShapeNode& shape, void* data)
|
void* GlRaster::prepare(const ShapeNode& shape, void* data, UpdateFlag flags)
|
||||||
{
|
{
|
||||||
//prepare shape data
|
//prepare shape data
|
||||||
GlShape* sdata = static_cast<GlShape*>(data);
|
GlShape* sdata = static_cast<GlShape*>(data);
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace tvg
|
||||||
class GlRaster : public RasterMethod
|
class GlRaster : public RasterMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void* prepare(const ShapeNode& shape, void* data) override;
|
void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) override;
|
||||||
static GlRaster* inst();
|
static GlRaster* inst();
|
||||||
static int init();
|
static int init();
|
||||||
static int term();
|
static int term();
|
||||||
|
|
|
@ -3,6 +3,7 @@ source_file = [
|
||||||
'tvgSwRaster.h',
|
'tvgSwRaster.h',
|
||||||
'tvgSwRaster.cpp',
|
'tvgSwRaster.cpp',
|
||||||
'tvgSwShape.cpp',
|
'tvgSwShape.cpp',
|
||||||
|
'tvgSwRle.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
swraster_dep = declare_dependency(
|
swraster_dep = declare_dependency(
|
||||||
|
|
|
@ -20,31 +20,58 @@
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
|
|
||||||
using namespace tvg;
|
using namespace tvg;
|
||||||
|
using SwPoint = Point;
|
||||||
|
|
||||||
|
constexpr auto SW_CURVE_TAG_CONIC = 0;
|
||||||
constexpr auto SW_CURVE_TAG_ON = 1;
|
constexpr auto SW_CURVE_TAG_ON = 1;
|
||||||
constexpr auto SW_CURVE_TAG_CUBIC = 2;
|
constexpr auto SW_CURVE_TAG_CUBIC = 2;
|
||||||
|
|
||||||
struct SwOutline
|
struct SwOutline
|
||||||
{
|
{
|
||||||
size_t* cntrs; //the contour end points
|
size_t* cntrs; //the contour end points
|
||||||
size_t cntrsCnt; //number of contours in glyph
|
size_t cntrsCnt; //number of contours in glyph
|
||||||
size_t reservedCntrsCnt;
|
size_t reservedCntrsCnt;
|
||||||
Point* pts; //the outline's points
|
SwPoint* pts; //the outline's points
|
||||||
size_t ptsCnt; //number of points in the glyph
|
size_t ptsCnt; //number of points in the glyph
|
||||||
size_t reservedPtsCnt;
|
size_t reservedPtsCnt;
|
||||||
char* tags; //the points flags
|
char* tags; //the points flags
|
||||||
size_t flags; //outline masks
|
size_t flags; //outline masks
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SwSpan
|
||||||
|
{
|
||||||
|
size_t x;
|
||||||
|
size_t y;
|
||||||
|
size_t len;
|
||||||
|
uint8_t coverage;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SwRleData
|
||||||
|
{
|
||||||
|
size_t alloc;
|
||||||
|
size_t size;
|
||||||
|
SwSpan *spans;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SwBBox
|
||||||
|
{
|
||||||
|
size_t xMin, yMin;
|
||||||
|
size_t xMax, yMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SwShape
|
struct SwShape
|
||||||
{
|
{
|
||||||
// SwRleRaster raster;
|
|
||||||
SwOutline* outline;
|
SwOutline* outline;
|
||||||
|
SwRleData rle;
|
||||||
|
SwBBox bbox;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata);
|
bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata);
|
||||||
void shapeDelOutline(const ShapeNode& shape, SwShape& sdata);
|
void shapeDelOutline(const ShapeNode& shape, SwShape& sdata);
|
||||||
bool shapeGenRle(const ShapeNode& shape, SwShape& sdata);
|
bool shapeGenRle(const ShapeNode& shape, SwShape& sdata);
|
||||||
bool shapeUpdateBBox(const ShapeNode& shape, SwShape& sdata);
|
void shapeDelRle(const ShapeNode& shape, SwShape& sdata);
|
||||||
|
bool shapeTransformOutline(const ShapeNode& shape, SwShape& sdata);
|
||||||
|
|
||||||
|
bool rleRender(SwShape& sdata);
|
||||||
|
|
||||||
#endif /* _TVG_SW_COMMON_H_ */
|
#endif /* _TVG_SW_COMMON_H_ */
|
||||||
|
|
|
@ -26,11 +26,12 @@
|
||||||
|
|
||||||
static SwRaster* pInst = nullptr;
|
static SwRaster* pInst = nullptr;
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
void* SwRaster::prepare(const ShapeNode& shape, void* data)
|
void* SwRaster::prepare(const ShapeNode& shape, void* data, UpdateFlag flags)
|
||||||
{
|
{
|
||||||
//prepare shape data
|
//prepare shape data
|
||||||
SwShape* sdata = static_cast<SwShape*>(data);
|
SwShape* sdata = static_cast<SwShape*>(data);
|
||||||
|
@ -39,18 +40,20 @@ void* SwRaster::prepare(const ShapeNode& shape, void* data)
|
||||||
assert(sdata);
|
assert(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags == UpdateFlag::None) return nullptr;
|
||||||
|
|
||||||
//invisible?
|
//invisible?
|
||||||
size_t alpha;
|
size_t alpha;
|
||||||
shape.fill(nullptr, nullptr, nullptr, &alpha);
|
shape.fill(nullptr, nullptr, nullptr, &alpha);
|
||||||
if (alpha == 0) return sdata;
|
if (alpha == 0) return sdata;
|
||||||
|
|
||||||
if (!shapeGenOutline(shape, *sdata)) return sdata;
|
if (flags & UpdateFlag::Path) {
|
||||||
|
if (!shapeGenOutline(shape, *sdata)) return sdata;
|
||||||
//TODO: From below sequence starts threading?
|
//TODO: From below sequence starts threading?
|
||||||
if (!shapeGenRle(shape, *sdata)) return sdata;
|
if (!shapeTransformOutline(shape, *sdata)) return sdata;
|
||||||
if (!shapeUpdateBBox(shape, *sdata)) return sdata;
|
if (!shapeGenRle(shape, *sdata)) return sdata;
|
||||||
|
shapeDelOutline(shape, *sdata);
|
||||||
shapeDelOutline(shape, *sdata);
|
}
|
||||||
|
|
||||||
return sdata;
|
return sdata;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
class SwRaster : public RasterMethod
|
class SwRaster : public RasterMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void* prepare(const ShapeNode& shape, void* data) override;
|
void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) override;
|
||||||
static SwRaster* inst();
|
static SwRaster* inst();
|
||||||
static int init();
|
static int init();
|
||||||
static int term();
|
static int term();
|
||||||
|
|
336
src/lib/sw_engine/tvgSwRle.cpp
Normal file
336
src/lib/sw_engine/tvgSwRle.cpp
Normal file
|
@ -0,0 +1,336 @@
|
||||||
|
/*
|
||||||
|
* 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_SW_RLE_H_
|
||||||
|
#define _TVG_SW_RLE_H_
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include "tvgSwCommon.h"
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* Internal Class Implementation */
|
||||||
|
/************************************************************************/
|
||||||
|
constexpr auto MAX_SPANS = 256;
|
||||||
|
|
||||||
|
using SwPtrDist = ptrdiff_t;
|
||||||
|
using TPos = long;
|
||||||
|
using TCoord = long;
|
||||||
|
using TArea = int;
|
||||||
|
|
||||||
|
struct TBand
|
||||||
|
{
|
||||||
|
TPos min, max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TCell
|
||||||
|
{
|
||||||
|
TPos x;
|
||||||
|
TCoord cover;
|
||||||
|
TArea area;
|
||||||
|
TCell *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RleWorker
|
||||||
|
{
|
||||||
|
TCoord ex, ey;
|
||||||
|
TPos exMin, exMax;
|
||||||
|
TPos eyMin, eyMax;
|
||||||
|
TPos exCnt, eyCnt;
|
||||||
|
|
||||||
|
TArea area;
|
||||||
|
TCoord cover;
|
||||||
|
|
||||||
|
TCell* cells;
|
||||||
|
SwPtrDist maxCells;
|
||||||
|
SwPtrDist numCells;
|
||||||
|
|
||||||
|
TPos x, y;
|
||||||
|
|
||||||
|
Point bezStack[32 * 3 + 1];
|
||||||
|
int levStack[32];
|
||||||
|
|
||||||
|
SwOutline* outline;
|
||||||
|
//SwBBox clipBox;
|
||||||
|
|
||||||
|
SwSpan spans[MAX_SPANS];
|
||||||
|
int spansCnt;
|
||||||
|
|
||||||
|
//render_span
|
||||||
|
//render_span_data;
|
||||||
|
int ySpan;
|
||||||
|
|
||||||
|
int bandSize;
|
||||||
|
int bandShoot;
|
||||||
|
|
||||||
|
jmp_buf jmpBuf;
|
||||||
|
|
||||||
|
void* buffer;
|
||||||
|
long bufferSize;
|
||||||
|
|
||||||
|
TCell** yCells;
|
||||||
|
TPos yCnt;
|
||||||
|
|
||||||
|
bool invalid;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool rleSweep(RleWorker& rw)
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool moveTo(SwPoint& pt)
|
||||||
|
{
|
||||||
|
printf("moveTo = %f %f\n", pt.x, pt.y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool lineTo(SwPoint& pt)
|
||||||
|
{
|
||||||
|
printf("lineTo = %f %f\n", pt.x, pt.y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool cubicTo(SwPoint& ctrl1, SwPoint& ctrl2, SwPoint& pt)
|
||||||
|
{
|
||||||
|
printf("cubicTo = ctrl1(%f %f) ctrl2(%f %f) pt(%f %f)\n", ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, pt.x, pt.y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool decomposeOutline(RleWorker& rw)
|
||||||
|
{
|
||||||
|
printf("decomposOutline\n");
|
||||||
|
auto outline = rw.outline;
|
||||||
|
assert(outline);
|
||||||
|
|
||||||
|
auto first = 0; //index of first point in contour
|
||||||
|
|
||||||
|
for (size_t n = 0; n < outline->cntrsCnt; ++n) {
|
||||||
|
auto last = outline->cntrs[n];
|
||||||
|
if (last < 0) goto invalid_outline;
|
||||||
|
|
||||||
|
auto limit = outline->pts + last;
|
||||||
|
assert(limit);
|
||||||
|
|
||||||
|
auto pt = outline->pts + first;
|
||||||
|
auto tags = outline->tags + first;
|
||||||
|
|
||||||
|
/* A contour cannot start with a cubic control point! */
|
||||||
|
if (tags[0] == SW_CURVE_TAG_CUBIC) goto invalid_outline;
|
||||||
|
|
||||||
|
if (!moveTo(outline->pts[first])) return false;
|
||||||
|
|
||||||
|
while (pt < limit) {
|
||||||
|
assert(++pt);
|
||||||
|
assert(++tags);
|
||||||
|
|
||||||
|
//emit a single line_to
|
||||||
|
if (tags[0] == SW_CURVE_TAG_ON) {
|
||||||
|
if (!lineTo(*pt)) return false;
|
||||||
|
continue;
|
||||||
|
//tag cubic
|
||||||
|
} else {
|
||||||
|
if (pt + 1 > limit || tags[1] != SW_CURVE_TAG_CUBIC)
|
||||||
|
goto invalid_outline;
|
||||||
|
|
||||||
|
pt += 2;
|
||||||
|
tags += 2;
|
||||||
|
|
||||||
|
if (pt <= limit) {
|
||||||
|
if (!cubicTo(pt[-2], pt[-1], pt[0])) return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!cubicTo(pt[-2], pt[-1], outline->pts[first])) return false;
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Close the contour with a line segment?
|
||||||
|
//if (!lineTo(outline->pts[first]));
|
||||||
|
close:
|
||||||
|
first = last + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
invalid_outline:
|
||||||
|
cout << "Invalid Outline!" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static TCell* findCell(RleWorker& rw)
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void recordCell(RleWorker& rw)
|
||||||
|
{
|
||||||
|
if (rw.area | rw.cover) {
|
||||||
|
TCell* cell = findCell(rw);
|
||||||
|
assert(cell);
|
||||||
|
cell->area += rw.area;
|
||||||
|
cell->cover += rw.cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool genRle(RleWorker& rw)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
if (setjmp(rw.jmpBuf) == 0) {
|
||||||
|
ret = decomposeOutline(rw);
|
||||||
|
if (!rw.invalid) recordCell(rw);
|
||||||
|
} else {
|
||||||
|
cout << "Memory Overflow" << endl;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* External Class Implementation */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
bool rleRender(SwShape& sdata)
|
||||||
|
{
|
||||||
|
constexpr auto RENDER_POOL_SIZE = 16384L;
|
||||||
|
constexpr auto BAND_SIZE = 40;
|
||||||
|
|
||||||
|
auto outline = sdata.outline;
|
||||||
|
assert(outline);
|
||||||
|
|
||||||
|
if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) return false;
|
||||||
|
|
||||||
|
assert(outline->cntrs && outline->pts);
|
||||||
|
assert(outline->ptsCnt == outline->cntrs[outline->cntrsCnt - 1] + 1);
|
||||||
|
|
||||||
|
//TODO: We can preserve several static workers in advance
|
||||||
|
RleWorker rw;
|
||||||
|
TCell buffer[RENDER_POOL_SIZE / sizeof(TCell)];
|
||||||
|
|
||||||
|
//Init Cells
|
||||||
|
rw.buffer = buffer;
|
||||||
|
rw.bufferSize = sizeof(buffer);
|
||||||
|
rw.yCells = reinterpret_cast<TCell**>(buffer);
|
||||||
|
rw.cells = nullptr;
|
||||||
|
rw.maxCells = 0;
|
||||||
|
rw.numCells = 0;
|
||||||
|
rw.area = 0;
|
||||||
|
rw.cover = 0;
|
||||||
|
rw.invalid = true;
|
||||||
|
rw.exMin = sdata.bbox.xMin;
|
||||||
|
rw.exMax = sdata.bbox.xMax;
|
||||||
|
rw.eyMin = sdata.bbox.yMin;
|
||||||
|
rw.eyMax = sdata.bbox.yMax;
|
||||||
|
rw.exCnt = rw.exMax - rw.exMin;
|
||||||
|
rw.eyCnt = rw.eyMax - rw.eyMin;
|
||||||
|
rw.outline = outline;
|
||||||
|
rw.bandSize = rw.bufferSize / (sizeof(TCell) * 8); //bandSize: 64
|
||||||
|
rw.bandShoot = 0;
|
||||||
|
//printf("bufferSize = %d, bbox(%d %d %d %d), exCnt(%d), eyCnt(%d), bandSize(%d)\n", rw.bufferSize, rw.exMin, rw.eyMin, rw.exMax, rw.eyMax, rw.exCnt, rw.eyCnt, rw.bandSize);
|
||||||
|
|
||||||
|
//Generate RLE
|
||||||
|
TBand bands[BAND_SIZE];
|
||||||
|
TBand* band;
|
||||||
|
|
||||||
|
/* set up vertical bands */
|
||||||
|
auto bandCnt = (rw.eyMax - rw.eyMin) / rw.bandSize;
|
||||||
|
if (bandCnt == 0) bandCnt = 1;
|
||||||
|
else if (bandCnt >= BAND_SIZE) bandCnt = BAND_SIZE - 1;
|
||||||
|
|
||||||
|
auto min = rw.eyMin;
|
||||||
|
auto yMax = rw.eyMax;
|
||||||
|
TPos max;
|
||||||
|
//printf("bandCnt(%d)\n", bandCnt);
|
||||||
|
|
||||||
|
for (int n = 0; n < bandCnt; ++n, min = max) {
|
||||||
|
max = min + rw.bandSize;
|
||||||
|
if (n == bandCnt -1 || max > yMax) max = yMax;
|
||||||
|
|
||||||
|
bands[0].min = min;
|
||||||
|
bands[0].max = max;
|
||||||
|
band = bands;
|
||||||
|
|
||||||
|
while (band >= bands) {
|
||||||
|
rw.yCells = static_cast<TCell**>(rw.buffer);
|
||||||
|
rw.yCnt = band->max - band->min;
|
||||||
|
|
||||||
|
auto cellStart = sizeof(TCell*) * rw.yCnt;
|
||||||
|
auto cellMod = cellStart % sizeof(TCell);
|
||||||
|
|
||||||
|
if (cellMod > 0) cellStart += sizeof(TCell) - cellMod;
|
||||||
|
|
||||||
|
auto cellEnd = rw.bufferSize;
|
||||||
|
cellEnd -= cellEnd % sizeof(TCell);
|
||||||
|
//printf("n:%d, cellStart(%d), cellEnd(%d) cellMod(%d)\n", n, cellStart, cellEnd, cellMod);
|
||||||
|
|
||||||
|
auto cellsMax = reinterpret_cast<TCell*>((char*)rw.buffer + cellEnd);
|
||||||
|
rw.cells = reinterpret_cast<TCell*>((char*)rw.buffer + cellStart);
|
||||||
|
|
||||||
|
if (rw.cells >= cellsMax) goto reduce_bands;
|
||||||
|
|
||||||
|
rw.maxCells = cellsMax - rw.cells;
|
||||||
|
if (rw.maxCells < 2) goto reduce_bands;
|
||||||
|
|
||||||
|
for (auto y = 0; y < rw.yCnt; ++y)
|
||||||
|
rw.yCells[y] = nullptr;
|
||||||
|
|
||||||
|
rw.numCells = 0;
|
||||||
|
rw.invalid = true;
|
||||||
|
rw.eyMin = band->min;
|
||||||
|
rw.eyMax = band->max;
|
||||||
|
rw.eyCnt = band->max - band->min;
|
||||||
|
|
||||||
|
if (!genRle(rw)) return -1;
|
||||||
|
|
||||||
|
rleSweep(rw);
|
||||||
|
--band;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
reduce_bands:
|
||||||
|
/* render pool overflow: we will reduce the render band by half */
|
||||||
|
auto bottom = band->min;
|
||||||
|
auto top = band->max;
|
||||||
|
auto middle = bottom + ((top - bottom) >> 1);
|
||||||
|
|
||||||
|
/* This is too complex for a single scanline; there must
|
||||||
|
be some problems */
|
||||||
|
if (middle == bottom) return -1;
|
||||||
|
|
||||||
|
if (bottom - top >= rw.bandSize) ++rw.bandShoot;
|
||||||
|
|
||||||
|
band[1].min = bottom;
|
||||||
|
band[1].max = middle;
|
||||||
|
band[0].min = middle;
|
||||||
|
band[0].max = top;
|
||||||
|
++band;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rw.bandShoot > 8 && rw.bandSize > 16)
|
||||||
|
rw.bandSize = rw.bandSize / 2;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _TVG_SW_RLE_H_ */
|
|
@ -69,7 +69,7 @@ static void outlineEnd(SwOutline& outline)
|
||||||
growOutlineContour(outline, 1);
|
growOutlineContour(outline, 1);
|
||||||
if (outline.ptsCnt > 0) {
|
if (outline.ptsCnt > 0) {
|
||||||
outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1;
|
outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1;
|
||||||
++outline.cntrs;
|
++outline.cntrsCnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,25 +150,77 @@ static bool outlineClose(SwOutline& outline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
static void initBBox(SwShape& sdata)
|
||||||
/* External Class Implementation */
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
bool shapeGenRle(const ShapeNode& shape, SwShape& sdata)
|
|
||||||
{
|
{
|
||||||
//TODO: rle
|
sdata.bbox.xMin = sdata.bbox.yMin = 0;
|
||||||
|
sdata.bbox.xMax = sdata.bbox.yMax = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool updateBBox(SwShape& sdata)
|
||||||
|
{
|
||||||
|
auto outline = sdata.outline;
|
||||||
|
assert(outline);
|
||||||
|
|
||||||
|
auto pt = outline->pts;
|
||||||
|
assert(pt);
|
||||||
|
|
||||||
|
if (outline->ptsCnt <= 0) {
|
||||||
|
initBBox(sdata);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto xMin = pt->x;
|
||||||
|
auto xMax = pt->y;
|
||||||
|
auto yMin = pt->y;
|
||||||
|
auto yMax = pt->y;
|
||||||
|
|
||||||
|
++pt;
|
||||||
|
|
||||||
|
for(size_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
|
||||||
|
assert(pt);
|
||||||
|
if (xMin > pt->x) xMin = pt->x;
|
||||||
|
if (xMax < pt->y) xMax = pt->x;
|
||||||
|
if (yMin > pt->y) yMin = pt->y;
|
||||||
|
if (yMax < pt->y) yMax = pt->y;
|
||||||
|
}
|
||||||
|
sdata.bbox.xMin = round(xMin - 0.49);
|
||||||
|
sdata.bbox.xMax = round(xMax + 0.49);
|
||||||
|
sdata.bbox.yMin = round(yMin - 0.49);
|
||||||
|
sdata.bbox.yMax = round(yMax + 0.49);
|
||||||
|
|
||||||
|
if (xMax - xMin < 1 || yMax - yMin < 1) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool shapeUpdateBBox(const ShapeNode& shape, SwShape& sdata)
|
/************************************************************************/
|
||||||
|
/* External Class Implementation */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
bool shapeTransformOutline(const ShapeNode& shape, SwShape& sdata)
|
||||||
{
|
{
|
||||||
//TODO:
|
//TODO:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void shapeDelRle(const ShapeNode& shape, SwShape& sdata)
|
||||||
|
{
|
||||||
|
if (sdata.rle.spans) free(sdata.rle.spans);
|
||||||
|
sdata.rle.spans = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool shapeGenRle(const ShapeNode& shape, SwShape& sdata)
|
||||||
|
{
|
||||||
|
shapeDelRle(shape, sdata);
|
||||||
|
if (!updateBBox(sdata)) return false;
|
||||||
|
return rleRender(sdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void shapeDelOutline(const ShapeNode& shape, SwShape& sdata)
|
void shapeDelOutline(const ShapeNode& shape, SwShape& sdata)
|
||||||
{
|
{
|
||||||
if (!sdata.outline) return;
|
if (!sdata.outline) return;
|
||||||
|
@ -185,6 +237,8 @@ void shapeDelOutline(const ShapeNode& shape, SwShape& sdata)
|
||||||
|
|
||||||
bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata)
|
bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata)
|
||||||
{
|
{
|
||||||
|
initBBox(sdata);
|
||||||
|
|
||||||
const PathCommand* cmds = nullptr;
|
const PathCommand* cmds = nullptr;
|
||||||
auto cmdCnt = shape.pathCommands(&cmds);
|
auto cmdCnt = shape.pathCommands(&cmds);
|
||||||
|
|
||||||
|
@ -233,6 +287,7 @@ bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata)
|
||||||
cout << "Outline was already allocated? How?" << endl;
|
cout << "Outline was already allocated? How?" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Probabry we can copy pts from shape directly.
|
||||||
growOutlinePoint(*outline, outlinePtsCnt);
|
growOutlinePoint(*outline, outlinePtsCnt);
|
||||||
growOutlineContour(*outline, outlineCntrsCnt);
|
growOutlineContour(*outline, outlineCntrsCnt);
|
||||||
|
|
||||||
|
@ -264,6 +319,9 @@ bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata)
|
||||||
|
|
||||||
outlineEnd(*outline);
|
outlineEnd(*outline);
|
||||||
|
|
||||||
|
//FIXME:
|
||||||
|
//outline->flags = SwOutline::FillRule::Winding;
|
||||||
|
|
||||||
sdata.outline = outline;
|
sdata.outline = outline;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <math.h>
|
||||||
#include "tizenvg.h"
|
#include "tizenvg.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -31,8 +32,9 @@ namespace tvg
|
||||||
class RasterMethod
|
class RasterMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum UpdateFlag { None = 0, Path = 1, Fill = 2, All = 3 };
|
||||||
virtual ~RasterMethod() {}
|
virtual ~RasterMethod() {}
|
||||||
virtual void* prepare(const ShapeNode& shape, void* data) = 0;
|
virtual void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ int ShapeNode :: update(RasterMethod* engine) noexcept
|
||||||
auto impl = pImpl.get();
|
auto impl = pImpl.get();
|
||||||
assert(impl);
|
assert(impl);
|
||||||
|
|
||||||
impl->edata = engine->prepare(*this, impl->edata);
|
impl->edata = engine->prepare(*this, impl->edata, RasterMethod::UpdateFlag::All);
|
||||||
if (impl->edata) return 0;
|
if (impl->edata) return 0;
|
||||||
return - 1;
|
return - 1;
|
||||||
}
|
}
|
||||||
|
@ -180,9 +180,9 @@ int ShapeNode :: fill(size_t* r, size_t* g, size_t* b, size_t* a) const noexcept
|
||||||
assert(impl);
|
assert(impl);
|
||||||
|
|
||||||
if (r) *r = impl->color[0];
|
if (r) *r = impl->color[0];
|
||||||
if (g) *g = impl->color[0];
|
if (g) *g = impl->color[1];
|
||||||
if (b) *b = impl->color[0];
|
if (b) *b = impl->color[2];
|
||||||
if (a) *a = impl->color[0];
|
if (a) *a = impl->color[3];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue