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.
@@ -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
- lines[0].W = lines[1].W = lines[2].W = width(img);
1291
- lines[0].H = lines[1].H = lines[2].H = height(img);
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={lines[0].H,-1};
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 <= lines[1].x1; x++) {
1304
- yRange.min = lines[0].H; yRange.max = -1;
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
- fillRect(img, x, yRange.min, 1, yRange.max - yRange.min + 1, c);
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 <= lines[2].x1; x++) {
1313
- yRange.min = lines[0].H; yRange.max = -1;
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
- fillRect(img, x, yRange.min, 1, yRange.max - yRange.min + 1, c);
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
- lines[0].W = lines[1].W = lines[2].W = lines[3].W = width(img);
1328
- lines[0].H = lines[1].H = lines[2].H = lines[3].H = height(img);
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)), lines[0].W - 1);
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 = { lines[0].H, -1 };
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 = lines[0].H; yRange.max = -1;
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
- fillRect(img, x,yRange.min, 1, yRange.max - yRange.min + 1, c);
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pxt-common-packages",
3
- "version": "10.4.6",
3
+ "version": "10.4.7",
4
4
  "description": "Microsoft MakeCode (PXT) common packages",
5
5
  "keywords": [
6
6
  "MakeCode",