pxt-common-packages 10.4.6 → 10.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/screen/image.cpp +85 -15
- package/package.json +1 -1
package/libs/screen/image.cpp
CHANGED
|
@@ -1267,6 +1267,46 @@ LineGenState initYRangeGenerator(int16_t X0, int16_t Y0, int16_t X1, int16_t Y1)
|
|
|
1267
1267
|
}
|
|
1268
1268
|
}
|
|
1269
1269
|
|
|
1270
|
+
// core of draw vertical line for repeatly calling, eg.: fillTriangle() or fillPolygon4()
|
|
1271
|
+
// value range/safety check not included
|
|
1272
|
+
// prepare "img->makeWritable();" and "uint8_t f = img->fillMask(c);" outside required.
|
|
1273
|
+
// bpp=4 support only right now
|
|
1274
|
+
void drawVLineCore(Image_ img, int x, int y, int h, uint8_t f) {
|
|
1275
|
+
uint8_t *p = img->pix(x, y);
|
|
1276
|
+
auto ptr = p;
|
|
1277
|
+
unsigned mask = 0x0f;
|
|
1278
|
+
if (y & 1)
|
|
1279
|
+
mask <<= 4;
|
|
1280
|
+
for (int i = 0; i < h; ++i) {
|
|
1281
|
+
if (mask == 0xf00) {
|
|
1282
|
+
if (h - i >= 2) {
|
|
1283
|
+
*++ptr = f;
|
|
1284
|
+
i++;
|
|
1285
|
+
continue;
|
|
1286
|
+
} else {
|
|
1287
|
+
mask = 0x0f;
|
|
1288
|
+
ptr++;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
*ptr = (*ptr & ~mask) | (f & mask);
|
|
1292
|
+
mask <<= 4;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
void drawVLine(Image_ img, int x, int y, int h, int c) {
|
|
1297
|
+
int H = height(img);
|
|
1298
|
+
uint8_t f = img->fillMask(c);
|
|
1299
|
+
if (x < 0 || x >= width(img) || y >= H || y + h - 1 < 0)
|
|
1300
|
+
return;
|
|
1301
|
+
if (y < 0){
|
|
1302
|
+
h += y;
|
|
1303
|
+
y = 0;
|
|
1304
|
+
}
|
|
1305
|
+
if (y + h > H)
|
|
1306
|
+
h = H - y;
|
|
1307
|
+
drawVLineCore(img, x, y, h, f);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1270
1310
|
void fillTriangle(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int c) {
|
|
1271
1311
|
if (x1 < x0) {
|
|
1272
1312
|
swap(x0, x1);
|
|
@@ -1287,8 +1327,9 @@ void fillTriangle(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, in
|
|
|
1287
1327
|
initYRangeGenerator(x1, y1, x2, y2)
|
|
1288
1328
|
};
|
|
1289
1329
|
|
|
1290
|
-
|
|
1291
|
-
lines[0].
|
|
1330
|
+
int W = width(img), H = height(img);
|
|
1331
|
+
lines[0].W = lines[1].W = lines[2].W = W;
|
|
1332
|
+
lines[0].H = lines[1].H = lines[2].H = H;
|
|
1292
1333
|
|
|
1293
1334
|
// We have 3 different sub-functions to generate Ys of edges, each particular edge maps to one of them.
|
|
1294
1335
|
// Use function pointers to avoid judging which function to call at every X.
|
|
@@ -1298,22 +1339,40 @@ void fillTriangle(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, in
|
|
|
1298
1339
|
FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];
|
|
1299
1340
|
FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];
|
|
1300
1341
|
|
|
1301
|
-
ValueRange yRange={
|
|
1342
|
+
ValueRange yRange = {H, -1};
|
|
1343
|
+
img->makeWritable();
|
|
1344
|
+
uint8_t f = img->fillMask(c);
|
|
1302
1345
|
|
|
1303
|
-
for (int x = lines[1].x0; x <=
|
|
1304
|
-
yRange.min =
|
|
1346
|
+
for (int x = lines[1].x0; x <= min(x1, W - 1); x++) {
|
|
1347
|
+
yRange.min = H;
|
|
1348
|
+
yRange.max = -1;
|
|
1305
1349
|
fpNext0(x, &lines[0], &yRange);
|
|
1306
1350
|
fpNext1(x, &lines[1], &yRange);
|
|
1307
|
-
|
|
1351
|
+
|
|
1352
|
+
if (x < 0 || yRange.min >= H || yRange.max < 0)
|
|
1353
|
+
continue;
|
|
1354
|
+
if (yRange.min < 0)
|
|
1355
|
+
yRange.min = 0;
|
|
1356
|
+
if (yRange.max >= H)
|
|
1357
|
+
yRange.max = H - 1;
|
|
1358
|
+
drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);
|
|
1308
1359
|
}
|
|
1309
1360
|
|
|
1310
1361
|
fpNext2(lines[2].x0, &lines[2], &yRange);
|
|
1311
1362
|
|
|
1312
|
-
for (int x = lines[2].x0 + 1; x <=
|
|
1313
|
-
yRange.min =
|
|
1363
|
+
for (int x = lines[2].x0 + 1; x <= min(x2, W - 1); x++) {
|
|
1364
|
+
yRange.min = H;
|
|
1365
|
+
yRange.max = -1;
|
|
1314
1366
|
fpNext0(x, &lines[0], &yRange);
|
|
1315
1367
|
fpNext2(x, &lines[2], &yRange);
|
|
1316
|
-
|
|
1368
|
+
|
|
1369
|
+
if (x < 0 || yRange.min >= H || yRange.max < 0)
|
|
1370
|
+
continue;
|
|
1371
|
+
if (yRange.min < 0)
|
|
1372
|
+
yRange.min = 0;
|
|
1373
|
+
if (yRange.max >= H)
|
|
1374
|
+
yRange.max = H - 1;
|
|
1375
|
+
drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);
|
|
1317
1376
|
}
|
|
1318
1377
|
}
|
|
1319
1378
|
|
|
@@ -1324,11 +1383,12 @@ void fillPolygon4(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, in
|
|
|
1324
1383
|
(x2 < x3) ? initYRangeGenerator(x2, y2, x3, y3) : initYRangeGenerator(x3, y3, x2, y2),
|
|
1325
1384
|
(x0 < x3) ? initYRangeGenerator(x0, y0, x3, y3) : initYRangeGenerator(x3, y3, x0, y0)};
|
|
1326
1385
|
|
|
1327
|
-
|
|
1328
|
-
lines[0].
|
|
1386
|
+
int W = width(img), H = height(img);
|
|
1387
|
+
lines[0].W = lines[1].W = lines[2].W = lines[3].W = W;
|
|
1388
|
+
lines[0].H = lines[1].H = lines[2].H = lines[3].H = H;
|
|
1329
1389
|
|
|
1330
1390
|
int minX = min(min(x0, x1), min(x2, x3));
|
|
1331
|
-
int maxX = min(max(max(x0, x1), max(x2, x3)),
|
|
1391
|
+
int maxX = min(max(max(x0, x1), max(x2, x3)), W - 1);
|
|
1332
1392
|
|
|
1333
1393
|
typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);
|
|
1334
1394
|
FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };
|
|
@@ -1337,15 +1397,25 @@ void fillPolygon4(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, in
|
|
|
1337
1397
|
FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];
|
|
1338
1398
|
FP_NEXT fpNext3 = nextFuncList[lines[3].nextFuncIndex];
|
|
1339
1399
|
|
|
1340
|
-
ValueRange yRange = {
|
|
1400
|
+
ValueRange yRange = { H, -1 };
|
|
1401
|
+
img->makeWritable();
|
|
1402
|
+
uint8_t f = img->fillMask(c);
|
|
1341
1403
|
|
|
1342
1404
|
for (int x = minX; x <= maxX; x++) {
|
|
1343
|
-
yRange.min =
|
|
1405
|
+
yRange.min = H;
|
|
1406
|
+
yRange.max = -1;
|
|
1344
1407
|
fpNext0(x, &lines[0], &yRange);
|
|
1345
1408
|
fpNext1(x, &lines[1], &yRange);
|
|
1346
1409
|
fpNext2(x, &lines[2], &yRange);
|
|
1347
1410
|
fpNext3(x, &lines[3], &yRange);
|
|
1348
|
-
|
|
1411
|
+
|
|
1412
|
+
if (x < 0 || yRange.min >= H || yRange.max < 0)
|
|
1413
|
+
continue;
|
|
1414
|
+
if (yRange.min < 0)
|
|
1415
|
+
yRange.min = 0;
|
|
1416
|
+
if (yRange.max >= H)
|
|
1417
|
+
yRange.max = H - 1;
|
|
1418
|
+
drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);
|
|
1349
1419
|
}
|
|
1350
1420
|
}
|
|
1351
1421
|
|