Showing
3 changed files
with
146 additions
and
102 deletions
| @@ -700,4 +700,9 @@ class PdfGraphics { | @@ -700,4 +700,9 @@ class PdfGraphics { | ||
| 700 | PdfNum(limit).output(buf); | 700 | PdfNum(limit).output(buf); |
| 701 | buf.putString(' M\n'); | 701 | buf.putString(' M\n'); |
| 702 | } | 702 | } |
| 703 | + | ||
| 704 | + void setLineDashPattern([List<int> array = const <int>[], int phase = 0]) { | ||
| 705 | + PdfArray.fromNum(array).output(buf); | ||
| 706 | + buf.putString(' $phase d\n'); | ||
| 707 | + } | ||
| 703 | } | 708 | } |
| @@ -20,24 +20,30 @@ part of widget; | @@ -20,24 +20,30 @@ part of widget; | ||
| 20 | 20 | ||
| 21 | enum DecorationPosition { background, foreground } | 21 | enum DecorationPosition { background, foreground } |
| 22 | 22 | ||
| 23 | +enum BorderStyle { none, solid, dashed, dotted } | ||
| 24 | + | ||
| 23 | @immutable | 25 | @immutable |
| 24 | class BoxBorder { | 26 | class BoxBorder { |
| 25 | - const BoxBorder( | ||
| 26 | - {this.left = false, | ||
| 27 | - this.top = false, | ||
| 28 | - this.right = false, | ||
| 29 | - this.bottom = false, | ||
| 30 | - this.color = PdfColors.black, | ||
| 31 | - this.width = 1.0}) | ||
| 32 | - : assert(color != null), | 27 | + const BoxBorder({ |
| 28 | + this.left = false, | ||
| 29 | + this.top = false, | ||
| 30 | + this.right = false, | ||
| 31 | + this.bottom = false, | ||
| 32 | + this.color = PdfColors.black, | ||
| 33 | + this.width = 1.0, | ||
| 34 | + this.style = BorderStyle.solid, | ||
| 35 | + }) : assert(color != null), | ||
| 33 | assert(width != null), | 36 | assert(width != null), |
| 34 | - assert(width >= 0.0); | 37 | + assert(width >= 0.0), |
| 38 | + assert(style != null); | ||
| 35 | 39 | ||
| 36 | final bool top; | 40 | final bool top; |
| 37 | final bool bottom; | 41 | final bool bottom; |
| 38 | final bool left; | 42 | final bool left; |
| 39 | final bool right; | 43 | final bool right; |
| 40 | 44 | ||
| 45 | + final BorderStyle style; | ||
| 46 | + | ||
| 41 | /// The color of the | 47 | /// The color of the |
| 42 | final PdfColor color; | 48 | final PdfColor color; |
| 43 | 49 | ||
| @@ -50,41 +56,63 @@ class BoxBorder { | @@ -50,41 +56,63 @@ class BoxBorder { | ||
| 50 | assert(box.width != null); | 56 | assert(box.width != null); |
| 51 | assert(box.height != null); | 57 | assert(box.height != null); |
| 52 | 58 | ||
| 53 | - if (top || bottom || left || right) { | ||
| 54 | - context.canvas | ||
| 55 | - ..setStrokeColor(color) | ||
| 56 | - ..setLineWidth(width); | 59 | + if (!(top || bottom || left || right)) { |
| 60 | + return; | ||
| 61 | + } | ||
| 57 | 62 | ||
| 58 | - if (top) { | ||
| 59 | - context.canvas.drawLine(box.x, box.top, box.right, box.top); | ||
| 60 | - } | 63 | + switch (style) { |
| 64 | + case BorderStyle.none: | ||
| 65 | + return; | ||
| 66 | + case BorderStyle.solid: | ||
| 67 | + break; | ||
| 68 | + case BorderStyle.dashed: | ||
| 69 | + context.canvas | ||
| 70 | + ..saveContext() | ||
| 71 | + ..setLineDashPattern(const <int>[3, 3]); | ||
| 72 | + break; | ||
| 73 | + case BorderStyle.dotted: | ||
| 74 | + context.canvas | ||
| 75 | + ..saveContext() | ||
| 76 | + ..setLineDashPattern(const <int>[1, 1]); | ||
| 77 | + break; | ||
| 78 | + } | ||
| 61 | 79 | ||
| 62 | - if (right) { | ||
| 63 | - if (!top) { | ||
| 64 | - context.canvas.moveTo(box.right, box.top); | ||
| 65 | - } | ||
| 66 | - context.canvas.lineTo(box.right, box.y); | 80 | + context.canvas |
| 81 | + ..setStrokeColor(color) | ||
| 82 | + ..setLineWidth(width); | ||
| 83 | + | ||
| 84 | + if (top) { | ||
| 85 | + context.canvas.drawLine(box.x, box.top, box.right, box.top); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + if (right) { | ||
| 89 | + if (!top) { | ||
| 90 | + context.canvas.moveTo(box.right, box.top); | ||
| 67 | } | 91 | } |
| 92 | + context.canvas.lineTo(box.right, box.y); | ||
| 93 | + } | ||
| 68 | 94 | ||
| 69 | - if (bottom) { | ||
| 70 | - if (!right) { | ||
| 71 | - context.canvas.moveTo(box.right, box.y); | ||
| 72 | - } | ||
| 73 | - context.canvas.lineTo(box.x, box.y); | 95 | + if (bottom) { |
| 96 | + if (!right) { | ||
| 97 | + context.canvas.moveTo(box.right, box.y); | ||
| 74 | } | 98 | } |
| 99 | + context.canvas.lineTo(box.x, box.y); | ||
| 100 | + } | ||
| 75 | 101 | ||
| 76 | - if (left) { | ||
| 77 | - if (!bottom) { | ||
| 78 | - context.canvas.moveTo(box.x, box.y); | ||
| 79 | - context.canvas.lineTo(box.x, box.top); | ||
| 80 | - } else if (right && top) { | ||
| 81 | - context.canvas.closePath(); | ||
| 82 | - } else { | ||
| 83 | - context.canvas.lineTo(box.x, box.top); | ||
| 84 | - } | 102 | + if (left) { |
| 103 | + if (!bottom) { | ||
| 104 | + context.canvas.moveTo(box.x, box.y); | ||
| 105 | + context.canvas.lineTo(box.x, box.top); | ||
| 106 | + } else if (right && top) { | ||
| 107 | + context.canvas.closePath(); | ||
| 108 | + } else { | ||
| 109 | + context.canvas.lineTo(box.x, box.top); | ||
| 85 | } | 110 | } |
| 111 | + } | ||
| 86 | 112 | ||
| 87 | - context.canvas.strokePath(); | 113 | + context.canvas.strokePath(); |
| 114 | + if (style != BorderStyle.solid) { | ||
| 115 | + context.canvas.restoreContext(); | ||
| 88 | } | 116 | } |
| 89 | } | 117 | } |
| 90 | 118 | ||
| @@ -349,6 +377,8 @@ class RadialGradient extends Gradient { | @@ -349,6 +377,8 @@ class RadialGradient extends Gradient { | ||
| 349 | 377 | ||
| 350 | enum BoxShape { circle, rectangle } | 378 | enum BoxShape { circle, rectangle } |
| 351 | 379 | ||
| 380 | +enum PaintPhase { all, background, foreground } | ||
| 381 | + | ||
| 352 | @immutable | 382 | @immutable |
| 353 | class BoxDecoration { | 383 | class BoxDecoration { |
| 354 | const BoxDecoration( | 384 | const BoxDecoration( |
| @@ -368,86 +398,94 @@ class BoxDecoration { | @@ -368,86 +398,94 @@ class BoxDecoration { | ||
| 368 | final DecorationImage image; | 398 | final DecorationImage image; |
| 369 | final Gradient gradient; | 399 | final Gradient gradient; |
| 370 | 400 | ||
| 371 | - void paint(Context context, PdfRect box) { | 401 | + void paint( |
| 402 | + Context context, | ||
| 403 | + PdfRect box, [ | ||
| 404 | + PaintPhase phase = PaintPhase.all, | ||
| 405 | + ]) { | ||
| 372 | assert(box.x != null); | 406 | assert(box.x != null); |
| 373 | assert(box.y != null); | 407 | assert(box.y != null); |
| 374 | assert(box.width != null); | 408 | assert(box.width != null); |
| 375 | assert(box.height != null); | 409 | assert(box.height != null); |
| 376 | 410 | ||
| 377 | - if (color != null) { | ||
| 378 | - switch (shape) { | ||
| 379 | - case BoxShape.rectangle: | ||
| 380 | - if (borderRadius == null) { | ||
| 381 | - context.canvas.drawRect(box.x, box.y, box.width, box.height); | ||
| 382 | - } else { | ||
| 383 | - context.canvas.drawRRect(box.x, box.y, box.width, box.height, | ||
| 384 | - borderRadius, borderRadius); | ||
| 385 | - } | ||
| 386 | - break; | ||
| 387 | - case BoxShape.circle: | ||
| 388 | - context.canvas.drawEllipse(box.x + box.width / 2.0, | ||
| 389 | - box.y + box.height / 2.0, box.width / 2.0, box.height / 2.0); | ||
| 390 | - break; | 411 | + if (phase == PaintPhase.all || phase == PaintPhase.background) { |
| 412 | + if (color != null) { | ||
| 413 | + switch (shape) { | ||
| 414 | + case BoxShape.rectangle: | ||
| 415 | + if (borderRadius == null) { | ||
| 416 | + context.canvas.drawRect(box.x, box.y, box.width, box.height); | ||
| 417 | + } else { | ||
| 418 | + context.canvas.drawRRect(box.x, box.y, box.width, box.height, | ||
| 419 | + borderRadius, borderRadius); | ||
| 420 | + } | ||
| 421 | + break; | ||
| 422 | + case BoxShape.circle: | ||
| 423 | + context.canvas.drawEllipse(box.x + box.width / 2.0, | ||
| 424 | + box.y + box.height / 2.0, box.width / 2.0, box.height / 2.0); | ||
| 425 | + break; | ||
| 426 | + } | ||
| 427 | + context.canvas | ||
| 428 | + ..setFillColor(color) | ||
| 429 | + ..fillPath(); | ||
| 391 | } | 430 | } |
| 392 | - context.canvas | ||
| 393 | - ..setFillColor(color) | ||
| 394 | - ..fillPath(); | ||
| 395 | - } | ||
| 396 | 431 | ||
| 397 | - if (gradient != null) { | ||
| 398 | - switch (shape) { | ||
| 399 | - case BoxShape.rectangle: | ||
| 400 | - if (borderRadius == null) { | ||
| 401 | - context.canvas.drawRect(box.x, box.y, box.width, box.height); | ||
| 402 | - } else { | ||
| 403 | - context.canvas.drawRRect(box.x, box.y, box.width, box.height, | ||
| 404 | - borderRadius, borderRadius); | ||
| 405 | - } | ||
| 406 | - break; | ||
| 407 | - case BoxShape.circle: | ||
| 408 | - context.canvas.drawEllipse(box.x + box.width / 2.0, | ||
| 409 | - box.y + box.height / 2.0, box.width / 2.0, box.height / 2.0); | ||
| 410 | - break; | ||
| 411 | - } | 432 | + if (gradient != null) { |
| 433 | + switch (shape) { | ||
| 434 | + case BoxShape.rectangle: | ||
| 435 | + if (borderRadius == null) { | ||
| 436 | + context.canvas.drawRect(box.x, box.y, box.width, box.height); | ||
| 437 | + } else { | ||
| 438 | + context.canvas.drawRRect(box.x, box.y, box.width, box.height, | ||
| 439 | + borderRadius, borderRadius); | ||
| 440 | + } | ||
| 441 | + break; | ||
| 442 | + case BoxShape.circle: | ||
| 443 | + context.canvas.drawEllipse(box.x + box.width / 2.0, | ||
| 444 | + box.y + box.height / 2.0, box.width / 2.0, box.height / 2.0); | ||
| 445 | + break; | ||
| 446 | + } | ||
| 412 | 447 | ||
| 413 | - gradient.paint(context, box); | ||
| 414 | - } | 448 | + gradient.paint(context, box); |
| 449 | + } | ||
| 415 | 450 | ||
| 416 | - if (image != null) { | ||
| 417 | - context.canvas.saveContext(); | ||
| 418 | - switch (shape) { | ||
| 419 | - case BoxShape.circle: | ||
| 420 | - context.canvas | ||
| 421 | - ..drawEllipse(box.x + box.width / 2.0, box.y + box.height / 2.0, | ||
| 422 | - box.width / 2.0, box.height / 2.0) | ||
| 423 | - ..clipPath(); | ||
| 424 | - | ||
| 425 | - break; | ||
| 426 | - case BoxShape.rectangle: | ||
| 427 | - if (borderRadius != null) { | 451 | + if (image != null) { |
| 452 | + context.canvas.saveContext(); | ||
| 453 | + switch (shape) { | ||
| 454 | + case BoxShape.circle: | ||
| 428 | context.canvas | 455 | context.canvas |
| 429 | - ..drawRRect(box.x, box.y, box.width, box.height, borderRadius, | ||
| 430 | - borderRadius) | 456 | + ..drawEllipse(box.x + box.width / 2.0, box.y + box.height / 2.0, |
| 457 | + box.width / 2.0, box.height / 2.0) | ||
| 431 | ..clipPath(); | 458 | ..clipPath(); |
| 432 | - } | ||
| 433 | - break; | 459 | + |
| 460 | + break; | ||
| 461 | + case BoxShape.rectangle: | ||
| 462 | + if (borderRadius != null) { | ||
| 463 | + context.canvas | ||
| 464 | + ..drawRRect(box.x, box.y, box.width, box.height, borderRadius, | ||
| 465 | + borderRadius) | ||
| 466 | + ..clipPath(); | ||
| 467 | + } | ||
| 468 | + break; | ||
| 469 | + } | ||
| 470 | + image.paint(context, box); | ||
| 471 | + context.canvas.restoreContext(); | ||
| 434 | } | 472 | } |
| 435 | - image.paint(context, box); | ||
| 436 | - context.canvas.restoreContext(); | ||
| 437 | } | 473 | } |
| 438 | 474 | ||
| 439 | - if (border != null) { | ||
| 440 | - switch (shape) { | ||
| 441 | - case BoxShape.circle: | ||
| 442 | - border.paintEllipse(context, box); | ||
| 443 | - break; | ||
| 444 | - case BoxShape.rectangle: | ||
| 445 | - if (borderRadius != null) { | ||
| 446 | - border.paintRRect(context, box, borderRadius); | ||
| 447 | - } else { | ||
| 448 | - border.paintRect(context, box); | ||
| 449 | - } | ||
| 450 | - break; | 475 | + if (phase == PaintPhase.all || phase == PaintPhase.foreground) { |
| 476 | + if (border != null) { | ||
| 477 | + switch (shape) { | ||
| 478 | + case BoxShape.circle: | ||
| 479 | + border.paintEllipse(context, box); | ||
| 480 | + break; | ||
| 481 | + case BoxShape.rectangle: | ||
| 482 | + if (borderRadius != null) { | ||
| 483 | + border.paintRRect(context, box, borderRadius); | ||
| 484 | + } else { | ||
| 485 | + border.paintRect(context, box); | ||
| 486 | + } | ||
| 487 | + break; | ||
| 488 | + } | ||
| 451 | } | 489 | } |
| 452 | } | 490 | } |
| 453 | } | 491 | } |
-
Please register or login to post a comment