Skip to content

Commit 2798981

Browse files
committed
fix QuickSort and use it in svg parsing
Signed-off-by: Slice <sergey.slice@gmail.com>
1 parent 5cb3712 commit 2798981

6 files changed

Lines changed: 392 additions & 229 deletions

File tree

rEFIt_UEFI/libeg/FloatLib.cpp

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -289,46 +289,48 @@ AsciiStrToFloat(IN CONST CHAR8 *String,
289289
return RETURN_SUCCESS;
290290
}
291291

292-
/*
293-
//Slice - this is my replacement for standard
294-
nsvg_qsort(void* Array, int Num, size_t Size,
295-
int (*compare)(void* a, void* b))
296-
usage qsort(Array, Num, sizeof(*Array), compare);
297-
where for example
298-
int compare(void *a, void* b)
299-
{
300-
if (*(float*)a > *(float*)b) return 1;
301-
if (*(float*)a < *(float*)b) return -1;
302-
return -0;
303-
}
304-
*/
305-
#if 0
306-
void QuickSort(void* Array, INTN Low, INTN High, INTN Size, INTN (*compare)(CONST void* a, CONST void* b)) {
292+
293+
//Slice my qsort implementation.
294+
void QuickSortWorker(UINT8* Array, INTN Low, INTN High, INTN Size,
295+
int(*compare)(CONST void* a, CONST void* b), void* Temp)
296+
{
307297
INTN i = Low, j = High;
308-
void *Med, *Temp;
309-
Med = Array + ((Low + High) / 2) * Size; // Central element, just pointer
310-
Temp = (__typeof__(Temp))AllocatePool(Size);
298+
299+
// СОЗДАЕМ ОТДЕЛЬНЫЙ БУФЕР ДЛЯ МЕДИАНЫ
300+
UINT8* medBuffer = (UINT8*)AllocatePool(Size);
301+
if (!medBuffer) return;
302+
UINT8* MedPtr = Array + ((Low + High) / 2) * Size; // Central element, just pointer
303+
304+
// КОПИРУЕМ ЗНАЧЕНИЕ центрального элемента
305+
CopyMem(medBuffer, MedPtr, Size);
306+
311307
// Sort around center
312308
while (i <= j)
313309
{
314-
while (compare((const void*)(Array+i*Size), (const void*)Med) == -1) i++;
315-
while (compare((const void*)(Array+j*Size), (const void*)Med) == 1) j--;
310+
while (compare((const void*)(Array + i * Size), medBuffer) == -1) ++i;
311+
while (compare((const void*)(Array + j * Size), medBuffer) == 1) --j;
316312
// Change
317313
if (i <= j) {
318-
memcpy(Temp, Array+i*Size, Size);
319-
memcpy(Array+i*Size, Array+j*Size, Size);
320-
memcpy(Array+j*Size, Temp, Size);
314+
CopyMem(Temp, Array + i * Size, Size);
315+
CopyMem(Array + i * Size, Array + j * Size, Size);
316+
CopyMem(Array + j * Size, Temp, Size);
321317
i++;
322318
j--;
323319
}
324320
}
325-
FreePool(Temp);
326-
// Recursion
327-
if (j > Low) QuickSort(Array, Low, j, Size, compare);
328-
if (High > i) QuickSort(Array, i, High, Size, compare);
321+
322+
FreePool(medBuffer);
323+
324+
if (j > Low) QuickSortWorker(Array, Low, j, Size, compare, Temp);
325+
if (High > i) QuickSortWorker(Array, i, High, Size, compare, Temp);
329326
}
330327

331-
#endif
328+
void QuickSort(void* Array, INTN Number, INTN Size, int(*compare)(CONST void* a, CONST void* b))
329+
{
330+
void* Buffer = (__typeof__(Buffer))AllocatePool(Size);
331+
QuickSortWorker((UINT8*)Array, 0, Number - 1, Size, compare, Buffer);
332+
FreePool(Buffer);
333+
}
332334

333335

334336
static UINT32 seed = 12345;

rEFIt_UEFI/libeg/FloatLib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ AsciiStrToFloat(IN CONST CHAR8 *String,
4848
void QuickSort(void* Array, INTN Low, INTN High, INTN Size,
4949
INTN (*compare)(CONST void* a, CONST void* b));
5050
#endif
51+
void QuickSort(void* Array, INTN Number, INTN Size, int(*compare)(CONST void* a, CONST void* b));
5152

5253

5354
#endif /* FloatLib_h */

rEFIt_UEFI/libeg/lodepng.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for
3333
#endif
3434

3535
#include "libegint.h"
36+
#include "FloatLib.h"
3637
#include "lodepng.h"
3738
//#include "../cpp_util/panic.h"
3839

@@ -71,6 +72,7 @@ with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way
7172
//#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch))
7273

7374
//Slice my qsort implementation.It can be moved into common library
75+
#if 0
7476
void QuickSortWorker(UINT8* Array, INTN Low, INTN High, INTN Size, int(*compare)(CONST void* a, CONST void* b), void* Temp)
7577
{
7678
INTN i = Low, j = High;
@@ -103,7 +105,7 @@ void QuickSort(void* Array, INTN Number, INTN Size, int(*compare)(CONST void* a,
103105
QuickSortWorker((UINT8*)Array, 0, Number - 1, Size, compare, Buffer);
104106
FreePool(Buffer);
105107
}
106-
108+
#endif
107109

108110
/*The malloc, realloc and free functions defined here with "lodepng_" in front
109111
of the name, so that you can easily change them to others related to your

rEFIt_UEFI/libeg/nanosvg.cpp

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
#include "../include/OneLinerMacros.h"
4848

4949
#ifndef DEBUG_ALL
50-
#define DEBUG_SVG 0
50+
#define DEBUG_SVG 1
5151
#else
5252
#define DEBUG_SVG DEBUG_ALL
5353
#endif
@@ -224,6 +224,7 @@ void nsvg__deleteShapes(NSVGshape* shape);
224224

225225
void nsvg__dumpFloat(CONST char* s, float* t, int N)
226226
{
227+
#if DEBUG_SVG
227228
DBG("%s: ", s);
228229
for(int i=0; i<N;i++)
229230
{
@@ -233,6 +234,7 @@ void nsvg__dumpFloat(CONST char* s, float* t, int N)
233234
DBG("%c%d.%06d ", ((b == 0) && sign)?'-':' ', b, (int)(fabsf((a-(float)b)*1.0e6f)));
234235
}
235236
DBG("\n");
237+
#endif
236238
}
237239

238240
static int nsvg__getIntegerDict(const char* s)
@@ -622,7 +624,7 @@ NSVGparser* nsvg__createParser()
622624
p->attr[0].strokeLineJoin = NSVG_JOIN_MITER;
623625
p->attr[0].strokeLineCap = NSVG_CAP_BUTT;
624626
p->attr[0].miterLimit = 4;
625-
p->attr[0].fillRule = NSVG_FILLRULE_NONZERO;
627+
p->attr[0].fillRule = NSVG_FILLRULE_EVENODD;
626628
p->attr[0].hasFill = 1;
627629
p->attr[0].visible = NSVG_VIS_DISPLAY | NSVG_VIS_VISIBLE;
628630
p->isText = false;
@@ -834,7 +836,7 @@ static void nsvg__lineTo(NSVGparser* p, float x, float y)
834836
dy = y - py;
835837

836838
// ===== ОТЛАДКА =====
837-
DBG("LINE_TO: from (%f,%f) to (%f,%f), dx=%f, dy=%f\n", px, py, x, y, dx, dy);
839+
// DBG("LINE_TO: from (%f,%f) to (%f,%f), dx=%f, dy=%f\n", px, py, x, y, dx, dy);
838840
// ===== КОНЕЦ ОТЛАДКИ =====
839841

840842
nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f);
@@ -847,8 +849,8 @@ static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2,
847849
{
848850
if (p->npts > 0) {
849851
// ===== ОТЛАДКА =====
850-
DBG("CUBIC_TO: cp1=(%f,%f), cp2=(%f,%f), end=(%f,%f)\n",
851-
cpx1, cpy1, cpx2, cpy2, x, y);
852+
// DBG("CUBIC_TO: cp1=(%f,%f), cp2=(%f,%f), end=(%f,%f)\n",
853+
// cpx1, cpy1, cpx2, cpy2, x, y);
852854
// ===== КОНЕЦ ОТЛАДКИ =====
853855
nsvg__addPoint(p, cpx1, cpy1);
854856
nsvg__addPoint(p, cpx2, cpy2);
@@ -1014,7 +1016,23 @@ static NSVGgradient* nsvg__createGradient(NSVGparser* p, NSVGshape* shape, NSVGg
10141016
// The shape width and height.
10151017
if (data->units == NSVG_OBJECT_SPACE) {
10161018
float localBounds[4];
1017-
nsvg__getLocalBounds(localBounds, shape, false); //, inv); //before any transform
1019+
// Если у shape есть clipList, берем bounds первого clipPath
1020+
if (shape->clipList)
1021+
{
1022+
NSVGclipPath *clipPath = nsvg__getClipPathWithIndex(p->image, shape->clipList->index);
1023+
if (clipPath && clipPath->shapes)
1024+
{
1025+
nsvg__getLocalBounds(localBounds, clipPath->shapes, false);
1026+
}
1027+
else
1028+
{
1029+
nsvg__getLocalBounds(localBounds, shape, false);
1030+
}
1031+
}
1032+
else
1033+
{
1034+
nsvg__getLocalBounds(localBounds, shape, false);
1035+
}
10181036

10191037
ox = localBounds[0];
10201038
oy = localBounds[1];
@@ -1287,6 +1305,11 @@ static void nsvg__addPath(NSVGparser* p, char closed, const char* fromWhere)
12871305
nsvg__delete(path, "nsvg__addPath3"_XS8);
12881306
return;
12891307
}
1308+
1309+
NSVGattrib* attr = nsvg__getAttr(p);
1310+
DBG("nsvg__addPath: shape=%s, added path with %d points, closed=%d\n",
1311+
attr->id, p->npts, closed);
1312+
12901313
path->closed = closed;
12911314
path->npts = p->npts;
12921315

@@ -1308,8 +1331,17 @@ static void nsvg__addPath(NSVGparser* p, char closed, const char* fromWhere)
13081331
path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]);
13091332
}
13101333
}
1311-
path->next = p->pathList;
1312-
p->pathList = path;
1334+
// path->next = p->pathList;
1335+
// p->pathList = path;
1336+
if (p->pathList == NULL) {
1337+
p->pathList = path;
1338+
} else {
1339+
NSVGpath* last = p->pathList;
1340+
while (last->next) last = last->next;
1341+
last->next = path;
1342+
}
1343+
1344+
DBG("nsvg__addPath: added path with %d points, closed=%d\n", p->npts, closed);
13131345
return;
13141346
}
13151347

@@ -2025,7 +2057,7 @@ static char nsvg__parseFillRule(const char* str)
20252057
else if (strcmp(str, "evenodd") == 0)
20262058
return NSVG_FILLRULE_EVENODD;
20272059
// TODO: handle inherit.
2028-
return NSVG_FILLRULE_NONZERO;
2060+
return NSVG_FILLRULE_EVENODD;
20292061
}
20302062

20312063
static const char* nsvg__getNextDashItem(const char* s, char* it)
@@ -3017,9 +3049,12 @@ static void nsvg__parsePath(NSVGparser* p, char** attr, bool addShape)
30173049
cmd = item[0];
30183050
// rargs = nsvg__getArgsPerElement(cmd);
30193051
if (cmd == 'M' || cmd == 'm') {
3020-
if (p->npts > 0)
3052+
if (p->npts > 0) {
3053+
DBG("nsvg__parsePath: closing subpath with %d points\n", p->npts);
30213054
nsvg__addPath(p, closedFlag, "nsvg__parsePath");
3055+
}
30223056
// Start new subpath.
3057+
DBG("nsvg__parsePath: starting new subpath\n");
30233058
nsvg__resetPath(p);
30243059
closedFlag = 0;
30253060
nargs = 0;
@@ -3831,6 +3866,7 @@ static void nsvg__parseGroup(NSVGparser* p, char** dict)
38313866
if (!curAttr) {
38323867
return;
38333868
}
3869+
38343870
// DBG("parse group\n");
38353871
NSVGgroup* group = (NSVGgroup*)nsvg__alloczero(sizeof(NSVGgroup), "nsvg__parseGroup"_XS8);
38363872
group->next = p->image->groups;
@@ -4347,20 +4383,20 @@ static void nsvg__startElement(void* ud, const char* el, char** dict)
43474383
newNode->next = curAttr->clipList;
43484384
curAttr->clipList = newNode;
43494385
}
4350-
DBG("ENTER CLIPPATH: id=%s, index=%d\n", dict[i+1], p->clipPath->index);
4386+
// DBG("ENTER CLIPPATH: id=%s, index=%d\n", dict[i+1], p->clipPath->index);
43514387
}
43524388
break;
43534389
}
43544390
}
43554391

43564392
// Отладочный вывод
4357-
DBG("ENTER CLIPPATH: stack list=[");
4358-
NSVGclipNode* node = curAttr->clipList;
4359-
while (node) {
4360-
DBG("%d ", node->index);
4361-
node = node->next;
4362-
}
4363-
DBG("]\n");
4393+
// DBG("ENTER CLIPPATH: stack list=[");
4394+
// NSVGclipNode* node = curAttr->clipList;
4395+
// while (node) {
4396+
// DBG("%d ", node->index);
4397+
// node = node->next;
4398+
// }
4399+
// DBG("]\n");
43644400

43654401
} else if (strcmp(el, "image") == 0) {
43664402
nsvg__parseEmbeddedPNG(p, dict);

rEFIt_UEFI/libeg/nanosvg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,8 @@ struct NSVGrasterizer
637637

638638
NSVGstencil* stencilList;
639639
int stencilCount; // количество clipPath
640+
641+
char currentShapeId[64]; // Идентификатор текущего shape для отладки
640642
};
641643

642644
#endif

0 commit comments

Comments
 (0)