David PHAM-VAN

Add soft mask

@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 - Automatically calculate Shape() bounding box 15 - Automatically calculate Shape() bounding box
16 - Improve gradient functions 16 - Improve gradient functions
17 - Add blend mode 17 - Add blend mode
  18 +- Add soft mask
18 19
19 ## 1.12.0 20 ## 1.12.0
20 21
@@ -37,5 +37,6 @@ export 'src/point.dart'; @@ -37,5 +37,6 @@ export 'src/point.dart';
37 export 'src/rect.dart'; 37 export 'src/rect.dart';
38 export 'src/shading.dart'; 38 export 'src/shading.dart';
39 export 'src/signature.dart'; 39 export 'src/signature.dart';
  40 +export 'src/smask.dart';
40 export 'src/ttf_parser.dart'; 41 export 'src/ttf_parser.dart';
41 export 'src/ttffont.dart'; 42 export 'src/ttffont.dart';
@@ -21,6 +21,8 @@ import 'package:meta/meta.dart'; @@ -21,6 +21,8 @@ import 'package:meta/meta.dart';
21 import 'data_types.dart'; 21 import 'data_types.dart';
22 import 'document.dart'; 22 import 'document.dart';
23 import 'object.dart'; 23 import 'object.dart';
  24 +import 'smask.dart';
  25 +
24 enum PdfBlendMode { 26 enum PdfBlendMode {
25 /// Selects the source colour, ignoring the backdrop 27 /// Selects the source colour, ignoring the backdrop
26 normal, 28 normal,
@@ -81,7 +83,7 @@ enum PdfBlendMode { @@ -81,7 +83,7 @@ enum PdfBlendMode {
81 @immutable 83 @immutable
82 class PdfGraphicState { 84 class PdfGraphicState {
83 /// Create a new graphic state 85 /// Create a new graphic state
84 - const PdfGraphicState({this.opacity, this.blendMode}); 86 + const PdfGraphicState({this.opacity, this.blendMode, this.softMask});
85 87
86 /// The opacity to apply to this graphic state 88 /// The opacity to apply to this graphic state
87 final double opacity; 89 final double opacity;
@@ -89,6 +91,8 @@ class PdfGraphicState { @@ -89,6 +91,8 @@ class PdfGraphicState {
89 /// The current blend mode to be used 91 /// The current blend mode to be used
90 final PdfBlendMode blendMode; 92 final PdfBlendMode blendMode;
91 93
  94 + final PdfSoftMask softMask;
  95 +
92 PdfDict output() { 96 PdfDict output() {
93 final params = PdfDict(); 97 final params = PdfDict();
94 98
@@ -99,11 +103,14 @@ class PdfGraphicState { @@ -99,11 +103,14 @@ class PdfGraphicState {
99 103
100 if (blendMode != null) { 104 if (blendMode != null) {
101 final bm = blendMode.toString(); 105 final bm = blendMode.toString();
102 - print(bm);  
103 params['/BM'] = 106 params['/BM'] =
104 PdfName('/' + bm.substring(13, 14).toUpperCase() + bm.substring(14)); 107 PdfName('/' + bm.substring(13, 14).toUpperCase() + bm.substring(14));
105 } 108 }
106 109
  110 + if (softMask != null) {
  111 + params['/SMask'] = softMask.output();
  112 + }
  113 +
107 return params; 114 return params;
108 } 115 }
109 116
@@ -112,7 +119,9 @@ class PdfGraphicState { @@ -112,7 +119,9 @@ class PdfGraphicState {
112 if (!(other is PdfGraphicState)) { 119 if (!(other is PdfGraphicState)) {
113 return false; 120 return false;
114 } 121 }
115 - return other.opacity == opacity; 122 + return other.opacity == opacity &&
  123 + other.blendMode == blendMode &&
  124 + other.softMask == softMask;
116 } 125 }
117 126
118 @override 127 @override
  1 +/*
  2 + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
  3 + *
  4 + * This library is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU Lesser General
  6 + * License as published by the Free Software Foundation; either
  7 + * version 2.1 of the License, or (at your option) any later version.
  8 + *
  9 + * This library is distributed in the hope that it will be useful,
  10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12 + * Lesser General License for more details.
  13 + *
  14 + * You should have received a copy of the GNU Lesser General
  15 + * License along with this library; if not, write to the Free Software
  16 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17 + */
  18 +
  19 +import 'package:meta/meta.dart';
  20 +import 'package:pdf/pdf.dart';
  21 +
  22 +import 'data_types.dart';
  23 +import 'document.dart';
  24 +import 'graphic_stream.dart';
  25 +import 'graphics.dart';
  26 +import 'rect.dart';
  27 +
  28 +class PdfSoftMask {
  29 + PdfSoftMask(this.document,
  30 + {@required PdfRect boundingBox,
  31 + bool isolated = false,
  32 + bool knockout = false,
  33 + bool invert = false})
  34 + : assert(boundingBox != null),
  35 + assert(isolated != null),
  36 + assert(knockout != null),
  37 + assert(invert != null) {
  38 + _mask = PdfGraphicXObject(document);
  39 + _mask.params['/BBox'] = PdfArray.fromNum([
  40 + boundingBox.x,
  41 + boundingBox.y,
  42 + boundingBox.width,
  43 + boundingBox.height,
  44 + ]);
  45 + if (isolated) {
  46 + _mask.params['/I'] = const PdfBool(true);
  47 + }
  48 + if (knockout) {
  49 + _mask.params['/K'] = const PdfBool(true);
  50 + }
  51 + _graphics = PdfGraphics(_mask, _mask.buf);
  52 +
  53 + if (invert) {
  54 + _tr = PdfFunction(
  55 + document,
  56 + data: [255, 0],
  57 + );
  58 + }
  59 + }
  60 +
  61 + final PdfDocument document;
  62 +
  63 + PdfGraphicXObject _mask;
  64 +
  65 + PdfGraphics _graphics;
  66 +
  67 + PdfGraphics getGraphics() => _graphics;
  68 +
  69 + PdfBaseFunction _tr;
  70 +
  71 + PdfDict output() {
  72 + final params = PdfDict({
  73 + '/S': const PdfName('/Luminosity'),
  74 + '/G': _mask.ref(),
  75 + });
  76 +
  77 + if (_tr != null) {
  78 + params['/TR'] = _tr.ref();
  79 + }
  80 +
  81 + return params;
  82 + }
  83 +}
@@ -21,7 +21,9 @@ import 'object_stream.dart'; @@ -21,7 +21,9 @@ import 'object_stream.dart';
21 class PdfXObject extends PdfObjectStream { 21 class PdfXObject extends PdfObjectStream {
22 PdfXObject(PdfDocument pdfDocument, String subtype, {bool isBinary = false}) 22 PdfXObject(PdfDocument pdfDocument, String subtype, {bool isBinary = false})
23 : super(pdfDocument, type: '/XObject', isBinary: isBinary) { 23 : super(pdfDocument, type: '/XObject', isBinary: isBinary) {
24 - params['/Subtype'] = PdfName(subtype); 24 + if (subtype != null) {
  25 + params['/Subtype'] = PdfName(subtype);
  26 + }
25 } 27 }
26 28
27 String get name => 'X$objser'; 29 String get name => 'X$objser';