Showing
7 changed files
with
89 additions
and
13 deletions
| @@ -20,6 +20,32 @@ part of pdf; | @@ -20,6 +20,32 @@ part of pdf; | ||
| 20 | 20 | ||
| 21 | enum PdfLineCap { joinMiter, joinRound, joinBevel } | 21 | enum PdfLineCap { joinMiter, joinRound, joinBevel } |
| 22 | 22 | ||
| 23 | +enum PdfTextRenderingMode { | ||
| 24 | + /// Fill text | ||
| 25 | + fill, | ||
| 26 | + | ||
| 27 | + /// Stroke text | ||
| 28 | + stroke, | ||
| 29 | + | ||
| 30 | + /// Fill, then stroke text | ||
| 31 | + fillAndStroke, | ||
| 32 | + | ||
| 33 | + /// Neither fill nor stroke text (invisible) | ||
| 34 | + invisible, | ||
| 35 | + | ||
| 36 | + /// Fill text and add to path for clipping | ||
| 37 | + fillAndClip, | ||
| 38 | + | ||
| 39 | + /// Stroke text and add to path for clipping | ||
| 40 | + strokeAndClip, | ||
| 41 | + | ||
| 42 | + /// Fill, then stroke text and add to path for clipping | ||
| 43 | + fillStrokeAndClip, | ||
| 44 | + | ||
| 45 | + /// Add text to path for clipping | ||
| 46 | + clip | ||
| 47 | +} | ||
| 48 | + | ||
| 23 | @immutable | 49 | @immutable |
| 24 | class _PdfGraphicsContext { | 50 | class _PdfGraphicsContext { |
| 25 | const _PdfGraphicsContext({@required this.ctm}) : assert(ctm != null); | 51 | const _PdfGraphicsContext({@required this.ctm}) : assert(ctm != null); |
| @@ -213,7 +239,18 @@ class PdfGraphics { | @@ -213,7 +239,18 @@ class PdfGraphics { | ||
| 213 | /// @param x coordinate | 239 | /// @param x coordinate |
| 214 | /// @param y coordinate | 240 | /// @param y coordinate |
| 215 | /// @param s String to draw | 241 | /// @param s String to draw |
| 216 | - void drawString(PdfFont font, double size, String s, double x, double y) { | 242 | + void drawString( |
| 243 | + PdfFont font, | ||
| 244 | + double size, | ||
| 245 | + String s, | ||
| 246 | + double x, | ||
| 247 | + double y, { | ||
| 248 | + double charSpace = 0, | ||
| 249 | + double wordSpace = 0, | ||
| 250 | + double scale = 1, | ||
| 251 | + PdfTextRenderingMode mode = PdfTextRenderingMode.fill, | ||
| 252 | + double rise = 0, | ||
| 253 | + }) { | ||
| 217 | if (!page.fonts.containsKey(font.name)) { | 254 | if (!page.fonts.containsKey(font.name)) { |
| 218 | page.fonts[font.name] = font; | 255 | page.fonts[font.name] = font; |
| 219 | } | 256 | } |
| @@ -223,8 +260,28 @@ class PdfGraphics { | @@ -223,8 +260,28 @@ class PdfGraphics { | ||
| 223 | buf.putString(' Td ${font.name} '); | 260 | buf.putString(' Td ${font.name} '); |
| 224 | buf.putNum(size); | 261 | buf.putNum(size); |
| 225 | buf.putString(' Tf '); | 262 | buf.putString(' Tf '); |
| 263 | + if (charSpace != 0) { | ||
| 264 | + buf.putNum(charSpace); | ||
| 265 | + buf.putString(' Tc '); | ||
| 266 | + } | ||
| 267 | + if (wordSpace != 0) { | ||
| 268 | + buf.putNum(wordSpace); | ||
| 269 | + buf.putString(' Tw '); | ||
| 270 | + } | ||
| 271 | + if (scale != 1) { | ||
| 272 | + buf.putNum(scale * 100); | ||
| 273 | + buf.putString(' Tz '); | ||
| 274 | + } | ||
| 275 | + if (rise != 0) { | ||
| 276 | + buf.putNum(rise); | ||
| 277 | + buf.putString(' Ts '); | ||
| 278 | + } | ||
| 279 | + if (mode != PdfTextRenderingMode.fill) { | ||
| 280 | + buf.putString('${mode.index} Tr '); | ||
| 281 | + } | ||
| 282 | + buf.putString('['); | ||
| 226 | buf.putStream(font.putText(s)); | 283 | buf.putStream(font.putText(s)); |
| 227 | - buf.putString(' Tj ET\n'); | 284 | + buf.putString(']TJ ET\n'); |
| 228 | } | 285 | } |
| 229 | 286 | ||
| 230 | /// Sets the color for drawing | 287 | /// Sets the color for drawing |
| @@ -20,11 +20,11 @@ part of pdf; | @@ -20,11 +20,11 @@ part of pdf; | ||
| 20 | 20 | ||
| 21 | class PdfTtfFont extends PdfFont { | 21 | class PdfTtfFont extends PdfFont { |
| 22 | /// Constructs a [PdfTtfFont] | 22 | /// Constructs a [PdfTtfFont] |
| 23 | - PdfTtfFont(PdfDocument pdfDocument, ByteData bytes) | 23 | + PdfTtfFont(PdfDocument pdfDocument, ByteData bytes, {bool protect = false}) |
| 24 | : font = TtfParser(bytes), | 24 | : font = TtfParser(bytes), |
| 25 | super._create(pdfDocument, subtype: '/TrueType') { | 25 | super._create(pdfDocument, subtype: '/TrueType') { |
| 26 | file = PdfObjectStream(pdfDocument, isBinary: true); | 26 | file = PdfObjectStream(pdfDocument, isBinary: true); |
| 27 | - unicodeCMap = PdfUnicodeCmap(pdfDocument); | 27 | + unicodeCMap = PdfUnicodeCmap(pdfDocument, protect); |
| 28 | descriptor = PdfFontDescriptor(this, file); | 28 | descriptor = PdfFontDescriptor(this, file); |
| 29 | widthsObject = PdfArrayObject(pdfDocument, <String>[]); | 29 | widthsObject = PdfArrayObject(pdfDocument, <String>[]); |
| 30 | } | 30 | } |
| @@ -19,12 +19,18 @@ | @@ -19,12 +19,18 @@ | ||
| 19 | part of pdf; | 19 | part of pdf; |
| 20 | 20 | ||
| 21 | class PdfUnicodeCmap extends PdfObjectStream { | 21 | class PdfUnicodeCmap extends PdfObjectStream { |
| 22 | - PdfUnicodeCmap(PdfDocument pdfDocument) : super(pdfDocument); | 22 | + PdfUnicodeCmap(PdfDocument pdfDocument, this.protect) : super(pdfDocument); |
| 23 | 23 | ||
| 24 | final List<int> cmap = <int>[0]; | 24 | final List<int> cmap = <int>[0]; |
| 25 | 25 | ||
| 26 | + final bool protect; | ||
| 27 | + | ||
| 26 | @override | 28 | @override |
| 27 | void _prepare() { | 29 | void _prepare() { |
| 30 | + if (protect) { | ||
| 31 | + cmap.fillRange(1, cmap.length, 0x20); | ||
| 32 | + } | ||
| 33 | + | ||
| 28 | buf.putString('/CIDInit/ProcSet findresource begin\n' | 34 | buf.putString('/CIDInit/ProcSet findresource begin\n' |
| 29 | '12 dict begin\n' | 35 | '12 dict begin\n' |
| 30 | 'begincmap\n' | 36 | 'begincmap\n' |
| @@ -144,13 +144,15 @@ class Font { | @@ -144,13 +144,15 @@ class Font { | ||
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | class TtfFont extends Font { | 146 | class TtfFont extends Font { |
| 147 | - TtfFont(this.data); | 147 | + TtfFont(this.data, {this.protect = false}); |
| 148 | 148 | ||
| 149 | final ByteData data; | 149 | final ByteData data; |
| 150 | 150 | ||
| 151 | + final bool protect; | ||
| 152 | + | ||
| 151 | @override | 153 | @override |
| 152 | PdfFont buildFont(PdfDocument pdfDocument) { | 154 | PdfFont buildFont(PdfDocument pdfDocument) { |
| 153 | - return PdfTtfFont(pdfDocument, data); | 155 | + return PdfTtfFont(pdfDocument, data, protect: protect); |
| 154 | } | 156 | } |
| 155 | 157 | ||
| 156 | @override | 158 | @override |
| @@ -218,11 +218,13 @@ class _Word extends _Span { | @@ -218,11 +218,13 @@ class _Word extends _Span { | ||
| 218 | PdfPoint point, | 218 | PdfPoint point, |
| 219 | ) { | 219 | ) { |
| 220 | context.canvas.drawString( | 220 | context.canvas.drawString( |
| 221 | - style.font.getFont(context), | ||
| 222 | - style.fontSize * textScaleFactor, | ||
| 223 | - text, | ||
| 224 | - point.x + offset.x, | ||
| 225 | - point.y + offset.y); | 221 | + style.font.getFont(context), |
| 222 | + style.fontSize * textScaleFactor, | ||
| 223 | + text, | ||
| 224 | + point.x + offset.x, | ||
| 225 | + point.y + offset.y, | ||
| 226 | + mode: style.renderingMode, | ||
| 227 | + ); | ||
| 226 | } | 228 | } |
| 227 | 229 | ||
| 228 | @override | 230 | @override |
| @@ -112,6 +112,7 @@ class TextStyle { | @@ -112,6 +112,7 @@ class TextStyle { | ||
| 112 | this.decorationColor, | 112 | this.decorationColor, |
| 113 | this.decorationStyle, | 113 | this.decorationStyle, |
| 114 | this.decorationThickness, | 114 | this.decorationThickness, |
| 115 | + this.renderingMode, | ||
| 115 | }) : assert(inherit || color != null), | 116 | }) : assert(inherit || color != null), |
| 116 | assert(inherit || fontNormal != null), | 117 | assert(inherit || fontNormal != null), |
| 117 | assert(inherit || fontBold != null), | 118 | assert(inherit || fontBold != null), |
| @@ -127,6 +128,7 @@ class TextStyle { | @@ -127,6 +128,7 @@ class TextStyle { | ||
| 127 | assert(inherit || decoration != null), | 128 | assert(inherit || decoration != null), |
| 128 | assert(inherit || decorationStyle != null), | 129 | assert(inherit || decorationStyle != null), |
| 129 | assert(inherit || decorationThickness != null), | 130 | assert(inherit || decorationThickness != null), |
| 131 | + assert(inherit || renderingMode != null), | ||
| 130 | fontNormal = fontNormal ?? | 132 | fontNormal = fontNormal ?? |
| 131 | (fontStyle != FontStyle.italic && fontWeight != FontWeight.bold | 133 | (fontStyle != FontStyle.italic && fontWeight != FontWeight.bold |
| 132 | ? font | 134 | ? font |
| @@ -163,6 +165,7 @@ class TextStyle { | @@ -163,6 +165,7 @@ class TextStyle { | ||
| 163 | decorationColor: null, | 165 | decorationColor: null, |
| 164 | decorationStyle: TextDecorationStyle.solid, | 166 | decorationStyle: TextDecorationStyle.solid, |
| 165 | decorationThickness: 1, | 167 | decorationThickness: 1, |
| 168 | + renderingMode: PdfTextRenderingMode.fill, | ||
| 166 | ); | 169 | ); |
| 167 | } | 170 | } |
| 168 | 171 | ||
| @@ -210,6 +213,8 @@ class TextStyle { | @@ -210,6 +213,8 @@ class TextStyle { | ||
| 210 | 213 | ||
| 211 | final double decorationThickness; | 214 | final double decorationThickness; |
| 212 | 215 | ||
| 216 | + final PdfTextRenderingMode renderingMode; | ||
| 217 | + | ||
| 213 | TextStyle copyWith({ | 218 | TextStyle copyWith({ |
| 214 | PdfColor color, | 219 | PdfColor color, |
| 215 | Font font, | 220 | Font font, |
| @@ -229,6 +234,7 @@ class TextStyle { | @@ -229,6 +234,7 @@ class TextStyle { | ||
| 229 | PdfColor decorationColor, | 234 | PdfColor decorationColor, |
| 230 | TextDecorationStyle decorationStyle, | 235 | TextDecorationStyle decorationStyle, |
| 231 | double decorationThickness, | 236 | double decorationThickness, |
| 237 | + PdfTextRenderingMode renderingMode, | ||
| 232 | }) { | 238 | }) { |
| 233 | return TextStyle( | 239 | return TextStyle( |
| 234 | inherit: inherit, | 240 | inherit: inherit, |
| @@ -250,6 +256,7 @@ class TextStyle { | @@ -250,6 +256,7 @@ class TextStyle { | ||
| 250 | decorationColor: decorationColor ?? this.decorationColor, | 256 | decorationColor: decorationColor ?? this.decorationColor, |
| 251 | decorationStyle: decorationStyle ?? this.decorationStyle, | 257 | decorationStyle: decorationStyle ?? this.decorationStyle, |
| 252 | decorationThickness: decorationThickness ?? this.decorationThickness, | 258 | decorationThickness: decorationThickness ?? this.decorationThickness, |
| 259 | + renderingMode: renderingMode ?? this.renderingMode, | ||
| 253 | ); | 260 | ); |
| 254 | } | 261 | } |
| 255 | 262 | ||
| @@ -342,6 +349,7 @@ class TextStyle { | @@ -342,6 +349,7 @@ class TextStyle { | ||
| 342 | decorationColor: other.decorationColor, | 349 | decorationColor: other.decorationColor, |
| 343 | decorationStyle: other.decorationStyle, | 350 | decorationStyle: other.decorationStyle, |
| 344 | decorationThickness: other.decorationThickness, | 351 | decorationThickness: other.decorationThickness, |
| 352 | + renderingMode: other.renderingMode, | ||
| 345 | ); | 353 | ); |
| 346 | } | 354 | } |
| 347 | 355 | ||
| @@ -370,5 +378,5 @@ class TextStyle { | @@ -370,5 +378,5 @@ class TextStyle { | ||
| 370 | 378 | ||
| 371 | @override | 379 | @override |
| 372 | String toString() => | 380 | String toString() => |
| 373 | - 'TextStyle(color:$color font:$font size:$fontSize weight:$fontWeight style:$fontStyle letterSpacing:$letterSpacing wordSpacing:$wordSpacing lineSpacing:$lineSpacing height:$height background:$background decoration:$decoration decorationColor:$decorationColor decorationStyle:$decorationStyle decorationThickness:$decorationThickness)'; | 381 | + 'TextStyle(color:$color font:$font size:$fontSize weight:$fontWeight style:$fontStyle letterSpacing:$letterSpacing wordSpacing:$wordSpacing lineSpacing:$lineSpacing height:$height background:$background decoration:$decoration decorationColor:$decorationColor decorationStyle:$decorationStyle decorationThickness:$decorationThickness, renderingMode:$renderingMode)'; |
| 374 | } | 382 | } |
-
Please register or login to post a comment