Last active
June 6, 2019 12:53
-
-
Save AgainPsychoX/e7402ed1c3e525d0b2b0a504cbc86a41 to your computer and use it in GitHub Desktop.
`PaintStyle` for `Paint` of `sky_engine`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:ui'; | |
/// A description of the style to use when drawing on a [Canvas]. | |
/// | |
/// Most APIs on [Canvas] take a [Paint] object to describe the style | |
/// to use for that operation. [PaintStyle] allows to be const | |
/// constructed and later in runtime forged into the [Paint] object. | |
class PaintStyle { | |
/// Whether to apply anti-aliasing to lines and images drawn on the | |
/// canvas. | |
/// | |
/// Defaults to true. | |
final bool isAntiAlias; | |
// Must be kept in sync with the default in paint.cc. | |
static const int _kColorDefault = 0xFF000000; | |
/// The color to use when stroking or filling a shape. | |
/// | |
/// Defaults to opaque black. | |
/// | |
/// See also: | |
/// | |
/// * [style], which controls whether to stroke or fill (or both). | |
/// * [colorFilter], which overrides [color]. | |
/// * [shader], which overrides [color] with more elaborate effects. | |
/// | |
/// This color is not used when compositing. To colorize a layer, use | |
/// [colorFilter]. | |
final Color color; | |
// Must be kept in sync with the default in paint.cc. | |
static final int _kBlendModeDefault = BlendMode.srcOver.index; | |
/// A blend mode to apply when a shape is drawn or a layer is composited. | |
/// | |
/// The source colors are from the shape being drawn (e.g. from | |
/// [Canvas.drawPath]) or layer being composited (the graphics that were drawn | |
/// between the [Canvas.saveLayer] and [Canvas.restore] calls), after applying | |
/// the [colorFilter], if any. | |
/// | |
/// The destination colors are from the background onto which the shape or | |
/// layer is being composited. | |
/// | |
/// Defaults to [BlendMode.srcOver]. | |
/// | |
/// See also: | |
/// | |
/// * [Canvas.saveLayer], which uses its [Paint]'s [blendMode] to composite | |
/// the layer when [restore] is called. | |
/// * [BlendMode], which discusses the user of [saveLayer] with [blendMode]. | |
final BlendMode blendMode; | |
/// Whether to paint inside shapes, the edges of shapes, or both. | |
/// | |
/// Defaults to [PaintingStyle.fill]. | |
final PaintingStyle style; | |
/// How wide to make edges drawn when [style] is set to | |
/// [PaintingStyle.stroke]. The width is given in logical pixels measured in | |
/// the direction orthogonal to the direction of the path. | |
/// | |
/// Defaults to 0.0, which correspond to a hairline width. | |
final double strokeWidth; | |
/// The kind of finish to place on the end of lines drawn when | |
/// [style] is set to [PaintingStyle.stroke]. | |
/// | |
/// Defaults to [StrokeCap.butt], i.e. no caps. | |
final StrokeCap strokeCap; | |
/// The kind of finish to place on the joins between segments. | |
/// | |
/// This applies to paths drawn when [style] is set to [PaintingStyle.stroke], | |
/// It does not apply to points drawn as lines with [Canvas.drawPoints]. | |
/// | |
/// Defaults to [StrokeJoin.miter], i.e. sharp corners. | |
/// | |
/// Some examples of joins: | |
/// | |
/// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/miter_4_join.mp4} | |
/// | |
/// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/round_join.mp4} | |
/// | |
/// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/bevel_join.mp4} | |
/// | |
/// The centers of the line segments are colored in the diagrams above to | |
/// highlight the joins, but in normal usage the join is the same color as the | |
/// line. | |
/// | |
/// See also: | |
/// | |
/// * [strokeMiterLimit] to control when miters are replaced by bevels when | |
/// this is set to [StrokeJoin.miter]. | |
/// * [strokeCap] to control what is drawn at the ends of the stroke. | |
/// * [StrokeJoin] for the definitive list of stroke joins. | |
final StrokeJoin strokeJoin; | |
// Must be kept in sync with the default in paint.cc. | |
static const double _kStrokeMiterLimitDefault = 4.0; | |
/// The limit for miters to be drawn on segments when the join is set to | |
/// [StrokeJoin.miter] and the [style] is set to [PaintingStyle.stroke]. If | |
/// this limit is exceeded, then a [StrokeJoin.bevel] join will be drawn | |
/// instead. This may cause some 'popping' of the corners of a path if the | |
/// angle between line segments is animated, as seen in the diagrams below. | |
/// | |
/// This limit is expressed as a limit on the length of the miter. | |
/// | |
/// Defaults to 4.0. Using zero as a limit will cause a [StrokeJoin.bevel] | |
/// join to be used all the time. | |
/// | |
/// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/miter_0_join.mp4} | |
/// | |
/// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/miter_4_join.mp4} | |
/// | |
/// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/dart-ui/miter_6_join.mp4} | |
/// | |
/// The centers of the line segments are colored in the diagrams above to | |
/// highlight the joins, but in normal usage the join is the same color as the | |
/// line. | |
/// | |
/// See also: | |
/// | |
/// * [strokeJoin] to control the kind of finish to place on the joins | |
/// between segments. | |
/// * [strokeCap] to control what is drawn at the ends of the stroke. | |
final double strokeMiterLimit; | |
/// A mask filter (for example, a blur) to apply to a shape after it has been | |
/// drawn but before it has been composited into the image. | |
/// | |
/// See [MaskFilter] for details. | |
final MaskFilter maskFilter; | |
/// Controls the performance vs quality trade-off to use when applying | |
/// filters, such as [maskFilter], or when drawing images, as with | |
/// [Canvas.drawImageRect] or [Canvas.drawImageNine]. | |
/// | |
/// Defaults to [FilterQuality.none]. | |
// TODO(ianh): verify that the image drawing methods actually respect this | |
final FilterQuality filterQuality; | |
/// The shader to use when stroking or filling a shape. | |
/// | |
/// When this is null, the [color] is used instead. | |
/// | |
/// See also: | |
/// | |
/// * [Gradient], a shader that paints a color gradient. | |
/// * [ImageShader], a shader that tiles an [Image]. | |
/// * [colorFilter], which overrides [shader]. | |
/// * [color], which is used if [shader] and [colorFilter] are null. | |
final Shader shader; | |
/// A color filter to apply when a shape is drawn or when a layer is | |
/// composited. | |
/// | |
/// See [ColorFilter] for details. | |
/// | |
/// When a shape is being drawn, [colorFilter] overrides [color] and [shader]. | |
final ColorFilter colorFilter; | |
/// Whether the colors of the image are inverted when drawn. | |
/// | |
/// Inverting the colors of an image applies a new color filter that will | |
/// be composed with any user provided color filters. This is primarily | |
/// used for implementing smart invert on iOS. | |
final bool invertColors; | |
const PaintStyle({ | |
this.isAntiAlias = true, | |
this.color = const Color(_kColorDefault), | |
this.blendMode = BlendMode.srcOver, | |
this.style = PaintingStyle.fill, | |
this.strokeWidth = 0.0, | |
this.strokeCap = StrokeCap.butt, | |
this.strokeJoin = StrokeJoin.miter, | |
this.strokeMiterLimit = 4.0, | |
this.maskFilter, // null | |
this.filterQuality = FilterQuality.none, | |
this.shader, // null | |
this.colorFilter, // null | |
this.invertColors = false, | |
}); | |
@override | |
String toString() { | |
final StringBuffer result = StringBuffer(); | |
String semicolon = ''; | |
result.write('Paint('); | |
if (style == PaintingStyle.stroke) { | |
result.write('$style'); | |
if (strokeWidth != 0.0) | |
result.write(' ${strokeWidth.toStringAsFixed(1)}'); | |
else | |
result.write(' hairline'); | |
if (strokeCap != StrokeCap.butt) | |
result.write(' $strokeCap'); | |
if (strokeJoin == StrokeJoin.miter) { | |
if (strokeMiterLimit != _kStrokeMiterLimitDefault) | |
result.write(' $strokeJoin up to ${strokeMiterLimit.toStringAsFixed(1)}'); | |
} else { | |
result.write(' $strokeJoin'); | |
} | |
semicolon = '; '; | |
} | |
if (isAntiAlias != true) { | |
result.write('${semicolon}antialias off'); | |
semicolon = '; '; | |
} | |
if (color != const Color(_kColorDefault)) { | |
if (color != null) | |
result.write('$semicolon$color'); | |
else | |
result.write('${semicolon}no color'); | |
semicolon = '; '; | |
} | |
if (blendMode.index != _kBlendModeDefault) { | |
result.write('$semicolon$blendMode'); | |
semicolon = '; '; | |
} | |
if (colorFilter != null) { | |
result.write('${semicolon}colorFilter: $colorFilter'); | |
semicolon = '; '; | |
} | |
if (maskFilter != null) { | |
result.write('${semicolon}maskFilter: $maskFilter'); | |
semicolon = '; '; | |
} | |
if (filterQuality != FilterQuality.none) { | |
result.write('${semicolon}filterQuality: $filterQuality'); | |
semicolon = '; '; | |
} | |
if (shader != null) { | |
result.write('${semicolon}shader: $shader'); | |
semicolon = '; '; | |
} | |
if (invertColors) | |
result.write('${semicolon}invert: $invertColors'); | |
result.write(')'); | |
return result.toString(); | |
} | |
Paint toPaint() { | |
Paint paint = Paint(); | |
if (this.isAntiAlias != true) | |
paint.isAntiAlias = this.isAntiAlias; | |
if (this.color != const Color(_kColorDefault)) | |
paint.color = this.color; | |
if (this.blendMode != BlendMode.srcOver) | |
paint.blendMode = this.blendMode; | |
if (this.style != PaintingStyle.fill) | |
paint.style = this.style; | |
if (this.strokeWidth != 0.0) | |
paint.strokeWidth = this.strokeWidth; | |
if (this.strokeCap != StrokeCap.butt) | |
paint.strokeCap = this.strokeCap; | |
if (this.strokeJoin != StrokeJoin.miter) | |
paint.strokeJoin = this.strokeJoin; | |
if (this.strokeMiterLimit != 4.0) | |
paint.strokeMiterLimit = this.strokeMiterLimit; | |
if (this.maskFilter != null) | |
paint.maskFilter = this.maskFilter; | |
if (this.filterQuality != FilterQuality.none) | |
paint.filterQuality = this.filterQuality; | |
if (this.shader != null) | |
paint.shader = this.shader; | |
if (this.colorFilter != null) | |
paint.colorFilter = this.colorFilter; | |
if (this.invertColors != false) | |
paint.invertColors = this.invertColors; | |
return paint; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment