Showing
3 changed files
with
307 additions
and
0 deletions
| @@ -37,6 +37,7 @@ export 'widgets/flex.dart'; | @@ -37,6 +37,7 @@ export 'widgets/flex.dart'; | ||
| 37 | export 'widgets/font.dart'; | 37 | export 'widgets/font.dart'; |
| 38 | export 'widgets/forms.dart'; | 38 | export 'widgets/forms.dart'; |
| 39 | export 'widgets/geometry.dart'; | 39 | export 'widgets/geometry.dart'; |
| 40 | +export 'widgets/grid_paper.dart'; | ||
| 40 | export 'widgets/grid_view.dart'; | 41 | export 'widgets/grid_view.dart'; |
| 41 | export 'widgets/icon.dart'; | 42 | export 'widgets/icon.dart'; |
| 42 | export 'widgets/image.dart'; | 43 | export 'widgets/image.dart'; |
pdf/lib/widgets/grid_paper.dart
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com> | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +import '../pdf.dart'; | ||
| 18 | +import 'box_border.dart'; | ||
| 19 | +import 'geometry.dart'; | ||
| 20 | + | ||
| 21 | +import 'widget.dart'; | ||
| 22 | + | ||
| 23 | +/// A widget that draws a rectilinear grid of lines. | ||
| 24 | +/// The grid is drawn over the [child] widget. | ||
| 25 | +class GridPaper extends SingleChildWidget { | ||
| 26 | + /// Creates a widget that draws a rectilinear grid lines. | ||
| 27 | + GridPaper({ | ||
| 28 | + PdfColor color = lineColor, | ||
| 29 | + double interval = 100, | ||
| 30 | + int divisions = 5, | ||
| 31 | + int subdivisions = 2, | ||
| 32 | + Widget child, | ||
| 33 | + }) : assert(divisions > 0, | ||
| 34 | + 'The "divisions" property must be greater than zero. If there were no divisions, the grid paper would not paint anything.'), | ||
| 35 | + assert(subdivisions > 0, | ||
| 36 | + 'The "subdivisions" property must be greater than zero. If there were no subdivisions, the grid paper would not paint anything.'), | ||
| 37 | + horizontalColor = color, | ||
| 38 | + verticalColor = color, | ||
| 39 | + horizontalInterval = interval, | ||
| 40 | + verticalInterval = interval, | ||
| 41 | + horizontalDivisions = divisions, | ||
| 42 | + verticalDivisions = divisions, | ||
| 43 | + horizontalSubdivisions = subdivisions, | ||
| 44 | + verticalSubdivisions = subdivisions, | ||
| 45 | + margin = EdgeInsets.zero, | ||
| 46 | + horizontalOffset = 0, | ||
| 47 | + verticalOffset = 0, | ||
| 48 | + border = const Border(), | ||
| 49 | + scale = 1, | ||
| 50 | + opacity = 0.5, | ||
| 51 | + super(child: child); | ||
| 52 | + | ||
| 53 | + GridPaper.millimeter({ | ||
| 54 | + PdfColor color = lineColor, | ||
| 55 | + Widget child, | ||
| 56 | + }) : horizontalColor = color, | ||
| 57 | + verticalColor = color, | ||
| 58 | + horizontalInterval = 5 * PdfPageFormat.cm, | ||
| 59 | + verticalInterval = 5 * PdfPageFormat.cm, | ||
| 60 | + horizontalDivisions = 5, | ||
| 61 | + verticalDivisions = 5, | ||
| 62 | + horizontalSubdivisions = 10, | ||
| 63 | + verticalSubdivisions = 10, | ||
| 64 | + margin = EdgeInsets.zero, | ||
| 65 | + horizontalOffset = 0, | ||
| 66 | + verticalOffset = 0, | ||
| 67 | + border = const Border(), | ||
| 68 | + scale = 1, | ||
| 69 | + opacity = 0.5, | ||
| 70 | + super(child: child); | ||
| 71 | + | ||
| 72 | + GridPaper.seyes({ | ||
| 73 | + this.margin = const EdgeInsets.only( | ||
| 74 | + top: 20 * PdfPageFormat.mm, | ||
| 75 | + bottom: 10 * PdfPageFormat.mm, | ||
| 76 | + left: 36 * PdfPageFormat.mm, | ||
| 77 | + right: 0, | ||
| 78 | + ), | ||
| 79 | + Widget child, | ||
| 80 | + }) : horizontalColor = const PdfColor.fromInt(0xffc8c8de), | ||
| 81 | + verticalColor = const PdfColor.fromInt(0xffc8c8de), | ||
| 82 | + horizontalInterval = 8 * PdfPageFormat.mm, | ||
| 83 | + verticalInterval = 8 * PdfPageFormat.mm, | ||
| 84 | + horizontalDivisions = 1, | ||
| 85 | + verticalDivisions = 4, | ||
| 86 | + horizontalSubdivisions = 1, | ||
| 87 | + verticalSubdivisions = 1, | ||
| 88 | + horizontalOffset = 0, | ||
| 89 | + verticalOffset = 1, | ||
| 90 | + border = const Border( | ||
| 91 | + left: BorderSide( | ||
| 92 | + color: PdfColor.fromInt(0xfff6bbcf), | ||
| 93 | + )), | ||
| 94 | + scale = 1, | ||
| 95 | + opacity = 1, | ||
| 96 | + super(child: child); | ||
| 97 | + | ||
| 98 | + GridPaper.collegeRuled({ | ||
| 99 | + this.margin = const EdgeInsets.only( | ||
| 100 | + top: 1 * PdfPageFormat.inch, | ||
| 101 | + bottom: 0.6 * PdfPageFormat.inch, | ||
| 102 | + left: 1.25 * PdfPageFormat.inch, | ||
| 103 | + right: 0, | ||
| 104 | + ), | ||
| 105 | + Widget child, | ||
| 106 | + }) : horizontalColor = lineColor, | ||
| 107 | + verticalColor = lineColor, | ||
| 108 | + horizontalInterval = double.infinity, | ||
| 109 | + verticalInterval = 9 / 32 * PdfPageFormat.inch, | ||
| 110 | + horizontalDivisions = 1, | ||
| 111 | + verticalDivisions = 1, | ||
| 112 | + horizontalSubdivisions = 1, | ||
| 113 | + verticalSubdivisions = 1, | ||
| 114 | + horizontalOffset = 0, | ||
| 115 | + verticalOffset = 1, | ||
| 116 | + border = const Border( | ||
| 117 | + left: BorderSide( | ||
| 118 | + color: PdfColors.red, | ||
| 119 | + )), | ||
| 120 | + scale = 1, | ||
| 121 | + opacity = 1, | ||
| 122 | + super(child: child); | ||
| 123 | + | ||
| 124 | + GridPaper.quad({ | ||
| 125 | + PdfColor color = lineColor, | ||
| 126 | + Widget child, | ||
| 127 | + }) : horizontalColor = color, | ||
| 128 | + verticalColor = color, | ||
| 129 | + horizontalInterval = PdfPageFormat.inch, | ||
| 130 | + verticalInterval = PdfPageFormat.inch, | ||
| 131 | + horizontalDivisions = 4, | ||
| 132 | + verticalDivisions = 4, | ||
| 133 | + horizontalSubdivisions = 1, | ||
| 134 | + verticalSubdivisions = 1, | ||
| 135 | + margin = EdgeInsets.zero, | ||
| 136 | + horizontalOffset = 0, | ||
| 137 | + verticalOffset = 0, | ||
| 138 | + border = const Border(), | ||
| 139 | + scale = 1, | ||
| 140 | + opacity = 0.5, | ||
| 141 | + super(child: child); | ||
| 142 | + | ||
| 143 | + GridPaper.engineering({ | ||
| 144 | + PdfColor color = lineColor, | ||
| 145 | + Widget child, | ||
| 146 | + }) : horizontalColor = color, | ||
| 147 | + verticalColor = color, | ||
| 148 | + horizontalInterval = PdfPageFormat.inch, | ||
| 149 | + verticalInterval = PdfPageFormat.inch, | ||
| 150 | + horizontalDivisions = 5, | ||
| 151 | + verticalDivisions = 5, | ||
| 152 | + horizontalSubdivisions = 2, | ||
| 153 | + verticalSubdivisions = 2, | ||
| 154 | + margin = EdgeInsets.zero, | ||
| 155 | + horizontalOffset = 0, | ||
| 156 | + verticalOffset = 0, | ||
| 157 | + border = const Border(), | ||
| 158 | + scale = 1, | ||
| 159 | + opacity = 0.5, | ||
| 160 | + super(child: child); | ||
| 161 | + | ||
| 162 | + static const lineColor = PdfColor.fromInt(0xffc3e8f3); | ||
| 163 | + | ||
| 164 | + /// The color to draw the horizontal lines in the grid. | ||
| 165 | + final PdfColor horizontalColor; | ||
| 166 | + | ||
| 167 | + /// The color to draw the vertical lines in the grid. | ||
| 168 | + final PdfColor verticalColor; | ||
| 169 | + | ||
| 170 | + /// The distance between the primary horizontal lines in the grid, in logical pixels. | ||
| 171 | + final double horizontalInterval; | ||
| 172 | + | ||
| 173 | + /// The distance between the primary vertical lines in the grid, in logical pixels. | ||
| 174 | + final double verticalInterval; | ||
| 175 | + | ||
| 176 | + /// The number of major horizontal divisions within each primary grid cell. | ||
| 177 | + final int horizontalDivisions; | ||
| 178 | + | ||
| 179 | + /// The number of major vertical divisions within each primary grid cell. | ||
| 180 | + final int verticalDivisions; | ||
| 181 | + | ||
| 182 | + /// The number of minor horizontal divisions within each major division, including the | ||
| 183 | + /// major division itself. | ||
| 184 | + final int horizontalSubdivisions; | ||
| 185 | + | ||
| 186 | + /// The number of minor vertical divisions within each major division, including the | ||
| 187 | + /// major division itself. | ||
| 188 | + final int verticalSubdivisions; | ||
| 189 | + | ||
| 190 | + /// The margin to apply to the horizontal and vertical lines | ||
| 191 | + final EdgeInsets margin; | ||
| 192 | + | ||
| 193 | + final int horizontalOffset; | ||
| 194 | + | ||
| 195 | + final int verticalOffset; | ||
| 196 | + | ||
| 197 | + final BoxBorder border; | ||
| 198 | + | ||
| 199 | + final double scale; | ||
| 200 | + | ||
| 201 | + final double opacity; | ||
| 202 | + | ||
| 203 | + @override | ||
| 204 | + void layout(Context context, BoxConstraints constraints, | ||
| 205 | + {bool parentUsesSize = false}) { | ||
| 206 | + box = PdfRect.fromPoints(PdfPoint.zero, constraints.biggest); | ||
| 207 | + if (child != null) { | ||
| 208 | + if (constraints.hasBoundedWidth && constraints.hasBoundedHeight) { | ||
| 209 | + final childConstraints = BoxConstraints( | ||
| 210 | + maxWidth: constraints.maxWidth - margin.horizontal, | ||
| 211 | + maxHeight: constraints.maxHeight - margin.vertical, | ||
| 212 | + ); | ||
| 213 | + child.layout(context, childConstraints, parentUsesSize: false); | ||
| 214 | + } else { | ||
| 215 | + child.layout(context, constraints, parentUsesSize: false); | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + assert(child.box != null); | ||
| 219 | + child.box = PdfRect.fromPoints( | ||
| 220 | + PdfPoint(margin.left, box.top - margin.top - child.box.height), | ||
| 221 | + child.box.size); | ||
| 222 | + } | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + @override | ||
| 226 | + void paint(Context context) { | ||
| 227 | + super.paint(context); | ||
| 228 | + paintChild(context); | ||
| 229 | + | ||
| 230 | + context.canvas.saveContext(); | ||
| 231 | + context.canvas.setGraphicState(PdfGraphicState(opacity: 0.5)); | ||
| 232 | + context.canvas.setStrokeColor(horizontalColor); | ||
| 233 | + final l = scale; | ||
| 234 | + final m = l / 2; | ||
| 235 | + final s = m / 2; | ||
| 236 | + | ||
| 237 | + final allHorizontalDivisions = | ||
| 238 | + (horizontalDivisions * horizontalSubdivisions).toDouble(); | ||
| 239 | + var n = horizontalOffset; | ||
| 240 | + for (var x = box.left + margin.left; | ||
| 241 | + x <= box.right - margin.right; | ||
| 242 | + x += horizontalInterval / allHorizontalDivisions) { | ||
| 243 | + context.canvas | ||
| 244 | + ..setLineWidth((n % (horizontalSubdivisions * horizontalDivisions) == 0) | ||
| 245 | + ? l | ||
| 246 | + : (n % horizontalSubdivisions == 0) | ||
| 247 | + ? m | ||
| 248 | + : s) | ||
| 249 | + ..drawLine(x, box.top, x, box.bottom) | ||
| 250 | + ..strokePath(); | ||
| 251 | + n++; | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + context.canvas.setStrokeColor(verticalColor); | ||
| 255 | + final allVerticalDivisions = | ||
| 256 | + (verticalDivisions * verticalSubdivisions).toDouble(); | ||
| 257 | + n = verticalOffset; | ||
| 258 | + for (var y = box.top - margin.top; | ||
| 259 | + y >= box.bottom + margin.bottom; | ||
| 260 | + y -= verticalInterval / allVerticalDivisions) { | ||
| 261 | + context.canvas | ||
| 262 | + ..setLineWidth((n % (verticalSubdivisions * verticalDivisions) == 0) | ||
| 263 | + ? l | ||
| 264 | + : (n % verticalSubdivisions == 0) | ||
| 265 | + ? m | ||
| 266 | + : s) | ||
| 267 | + ..drawLine(box.left, y, box.right, y) | ||
| 268 | + ..strokePath(); | ||
| 269 | + n++; | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + if (border.left.style != BorderStyle.none) { | ||
| 273 | + context.canvas | ||
| 274 | + ..setStrokeColor(border.left.color) | ||
| 275 | + ..setLineWidth(border.left.width) | ||
| 276 | + ..drawLine( | ||
| 277 | + box.left + margin.left, box.top, box.left + margin.left, box.bottom) | ||
| 278 | + ..strokePath(); | ||
| 279 | + } | ||
| 280 | + if (border.right.style != BorderStyle.none) { | ||
| 281 | + context.canvas | ||
| 282 | + ..setStrokeColor(border.right.color) | ||
| 283 | + ..setLineWidth(border.right.width) | ||
| 284 | + ..drawLine(box.right - margin.right, box.top, box.right - margin.right, | ||
| 285 | + box.bottom) | ||
| 286 | + ..strokePath(); | ||
| 287 | + } | ||
| 288 | + if (border.top.style != BorderStyle.none) { | ||
| 289 | + context.canvas | ||
| 290 | + ..setStrokeColor(border.top.color) | ||
| 291 | + ..setLineWidth(border.top.width) | ||
| 292 | + ..drawLine( | ||
| 293 | + box.left, box.top - margin.top, box.right, box.top - margin.top) | ||
| 294 | + ..strokePath(); | ||
| 295 | + } | ||
| 296 | + if (border.bottom.style != BorderStyle.none) { | ||
| 297 | + context.canvas | ||
| 298 | + ..setStrokeColor(border.bottom.color) | ||
| 299 | + ..setLineWidth(border.bottom.width) | ||
| 300 | + ..drawLine(box.left, box.bottom + margin.bottom, box.right, | ||
| 301 | + box.bottom + margin.bottom) | ||
| 302 | + ..strokePath(); | ||
| 303 | + } | ||
| 304 | + } | ||
| 305 | +} |
-
Please register or login to post a comment