mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Some Paint dartdocs (and style tweaks)
This commit is contained in:
parent
bf45869dbf
commit
610916bb51
@ -73,8 +73,10 @@ class Path extends NativeFieldWrapperClass2 {
|
||||
Path shift(Offset offset) native "Path_shift";
|
||||
}
|
||||
|
||||
/// Blur styles. These mirror SkBlurStyle and must be kept in sync.
|
||||
/// Styles to use for blurs in [MaskFilter] objects.
|
||||
enum BlurStyle {
|
||||
// These mirror SkBlurStyle and must be kept in sync.
|
||||
|
||||
/// Fuzzy inside and outside.
|
||||
normal,
|
||||
|
||||
@ -88,24 +90,29 @@ enum BlurStyle {
|
||||
inner,
|
||||
}
|
||||
|
||||
// Convert constructor parameters to the SkBlurMaskFilter::BlurFlags type.
|
||||
int _makeBlurFlags(bool ignoreTransform, bool highQuality) {
|
||||
int flags = 0;
|
||||
if (ignoreTransform)
|
||||
flags |= 0x01;
|
||||
if (highQuality)
|
||||
flags |= 0x02;
|
||||
return flags;
|
||||
}
|
||||
|
||||
class MaskFilter extends NativeFieldWrapperClass2 {
|
||||
MaskFilter.blur(BlurStyle style, double sigma,
|
||||
{bool ignoreTransform: false, bool highQuality: false}) {
|
||||
MaskFilter.blur(BlurStyle style, double sigma, {
|
||||
bool ignoreTransform: false,
|
||||
bool highQuality: false
|
||||
}) {
|
||||
_constructor(style.index, sigma, _makeBlurFlags(ignoreTransform, highQuality));
|
||||
}
|
||||
void _constructor(int style, double sigma, int flags) native "MaskFilter_constructor";
|
||||
|
||||
// Convert constructor parameters to the SkBlurMaskFilter::BlurFlags type.
|
||||
static int _makeBlurFlags(bool ignoreTransform, bool highQuality) {
|
||||
int flags = 0;
|
||||
if (ignoreTransform)
|
||||
flags |= 0x01;
|
||||
if (highQuality)
|
||||
flags |= 0x02;
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
|
||||
/// A description of a filter to apply when drawing with a particular [Paint].
|
||||
///
|
||||
/// See [Paint.colorFilter].
|
||||
class ColorFilter extends NativeFieldWrapperClass2 {
|
||||
ColorFilter.mode(Color color, TransferMode transferMode) {
|
||||
_constructor(color, transferMode);
|
||||
@ -113,6 +120,8 @@ class ColorFilter extends NativeFieldWrapperClass2 {
|
||||
void _constructor(Color color, TransferMode transferMode) native "ColorFilter_constructor";
|
||||
}
|
||||
|
||||
/// Base class for objects such as [Gradient] and [ImageShader] which
|
||||
/// correspond to shaders.
|
||||
abstract class Shader extends NativeFieldWrapperClass2 { }
|
||||
|
||||
/// Defines what happens at the edge of the gradient.
|
||||
@ -125,12 +134,6 @@ enum TileMode {
|
||||
mirror
|
||||
}
|
||||
|
||||
void _validateColorStops(List<Color> colors, List<double> colorStops) {
|
||||
if (colorStops != null && (colors == null || colors.length != colorStops.length)) {
|
||||
throw new ArgumentError("[colors] and [colorStops] parameters must be equal length.");
|
||||
}
|
||||
}
|
||||
|
||||
class Gradient extends Shader {
|
||||
/// Creates a Gradient object that is not initialized.
|
||||
///
|
||||
@ -169,6 +172,11 @@ class Gradient extends Shader {
|
||||
_initRadial(center, radius, colors, colorStops, tileMode.index);
|
||||
}
|
||||
void _initRadial(Point center, double radius, List<Color> colors, List<double> colorStops, int tileMode) native "Gradient_initRadial";
|
||||
|
||||
static void _validateColorStops(List<Color> colors, List<double> colorStops) {
|
||||
if (colorStops != null && (colors == null || colors.length != colorStops.length))
|
||||
throw new ArgumentError("[colors] and [colorStops] parameters must be equal length.");
|
||||
}
|
||||
}
|
||||
|
||||
class ImageShader extends Shader {
|
||||
|
||||
@ -4,8 +4,12 @@
|
||||
|
||||
part of dart_ui;
|
||||
|
||||
/// List of predefined filter quality modes. This list comes from Skia's
|
||||
/// SkFitlerQuality.h and the values (order) should be kept in sync.
|
||||
// List of predefined filter quality modes. This list comes from Skia's
|
||||
// SkFilterQuality.h and the values (order) should be kept in sync.
|
||||
|
||||
/// Quality levels for image filters.
|
||||
///
|
||||
/// See [Paint.filterQuality].
|
||||
enum FilterQuality {
|
||||
none,
|
||||
low,
|
||||
|
||||
@ -22,17 +22,18 @@
|
||||
namespace blink {
|
||||
namespace {
|
||||
|
||||
// Must match Paint._value getter in Paint.dart.
|
||||
enum PaintFields {
|
||||
kStyle,
|
||||
kStrokeWidth,
|
||||
kStrokeCap,
|
||||
kIsAntiAlias,
|
||||
kColor,
|
||||
kColorFilter,
|
||||
kFilterQuality,
|
||||
kMaskFilter,
|
||||
kShader,
|
||||
kStyle,
|
||||
kTransferMode,
|
||||
kStrokeCap,
|
||||
kColorFilter,
|
||||
kMaskFilter,
|
||||
kFilterQuality,
|
||||
kShader,
|
||||
|
||||
// kNumberOfPaintFields must be last.
|
||||
kNumberOfPaintFields,
|
||||
@ -73,26 +74,27 @@ Paint DartConverter<Paint>::FromDart(Dart_Handle dart_paint) {
|
||||
}
|
||||
|
||||
SkPaint& paint = result.sk_paint;
|
||||
|
||||
if (!Dart_IsNull(values[kStyle]))
|
||||
paint.setStyle(DartConverter<PaintingStyle>::FromDart(values[kStyle]));
|
||||
if (!Dart_IsNull(values[kStrokeWidth]))
|
||||
paint.setStrokeWidth(DartConverter<SkScalar>::FromDart(values[kStrokeWidth]));
|
||||
if (!Dart_IsNull(values[kStrokeCap]))
|
||||
paint.setStrokeCap(DartConverter<StrokeCap>::FromDart(values[kStrokeCap]));
|
||||
if (!Dart_IsNull(values[kIsAntiAlias]))
|
||||
paint.setAntiAlias(DartConverter<bool>::FromDart(values[kIsAntiAlias]));
|
||||
if (!Dart_IsNull(values[kColor]))
|
||||
paint.setColor(DartConverter<CanvasColor>::FromDart(values[kColor]));
|
||||
if (!Dart_IsNull(values[kColorFilter]))
|
||||
paint.setColorFilter(DartConverter<ColorFilter*>::FromDart(values[kColorFilter])->filter());
|
||||
if (!Dart_IsNull(values[kFilterQuality]))
|
||||
paint.setFilterQuality(DartConverter<FilterQuality>::FromDart(values[kFilterQuality]));
|
||||
if (!Dart_IsNull(values[kMaskFilter]))
|
||||
paint.setMaskFilter(DartConverter<MaskFilter*>::FromDart(values[kMaskFilter])->filter());
|
||||
if (!Dart_IsNull(values[kShader]))
|
||||
paint.setShader(DartConverter<Shader*>::FromDart(values[kShader])->shader());
|
||||
if (!Dart_IsNull(values[kStyle]))
|
||||
paint.setStyle(DartConverter<PaintingStyle>::FromDart(values[kStyle]));
|
||||
if (!Dart_IsNull(values[kTransferMode]))
|
||||
paint.setXfermodeMode(DartConverter<TransferMode>::FromDart(values[kTransferMode]));
|
||||
if (!Dart_IsNull(values[kStrokeCap]))
|
||||
paint.setStrokeCap(DartConverter<StrokeCap>::FromDart(values[kStrokeCap]));
|
||||
if (!Dart_IsNull(values[kColorFilter]))
|
||||
paint.setColorFilter(DartConverter<ColorFilter*>::FromDart(values[kColorFilter])->filter());
|
||||
if (!Dart_IsNull(values[kMaskFilter]))
|
||||
paint.setMaskFilter(DartConverter<MaskFilter*>::FromDart(values[kMaskFilter])->filter());
|
||||
if (!Dart_IsNull(values[kFilterQuality]))
|
||||
paint.setFilterQuality(DartConverter<FilterQuality>::FromDart(values[kFilterQuality]));
|
||||
if (!Dart_IsNull(values[kShader]))
|
||||
paint.setShader(DartConverter<Shader*>::FromDart(values[kShader])->shader());
|
||||
|
||||
result.is_null = false;
|
||||
return result;
|
||||
|
||||
@ -4,70 +4,142 @@
|
||||
|
||||
part of dart_ui;
|
||||
|
||||
/// Styles to use for line endings.
|
||||
///
|
||||
/// See [Paint.strokeCap].
|
||||
enum StrokeCap {
|
||||
/// Begin/end contours with no extension.
|
||||
/// Begin and end contours with a flat edge and no extension.
|
||||
butt,
|
||||
|
||||
/// Begin/end contours with a semi-circle extension.
|
||||
/// Begin and end contours with a semi-circle extension.
|
||||
round,
|
||||
|
||||
/// Begin/end contours with a half square extension.
|
||||
/// Begin and end contours with a half square extension. This is
|
||||
/// similar to extending each contour by half the stroke width (as
|
||||
/// given by [Paint.strokeWidth]).
|
||||
square,
|
||||
}
|
||||
|
||||
/// 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.
|
||||
class Paint {
|
||||
double strokeWidth;
|
||||
bool isAntiAlias = true;
|
||||
Color color = const Color(0xFF000000);
|
||||
ColorFilter colorFilter;
|
||||
FilterQuality filterQuality;
|
||||
MaskFilter maskFilter;
|
||||
Shader shader;
|
||||
/// Whether to paint inside shapes, the edges of shapes, or both.
|
||||
///
|
||||
/// If null, defaults to [PaintingStyle.fill].
|
||||
PaintingStyle style;
|
||||
TransferMode transferMode;
|
||||
|
||||
/// How wide to make edges drawn when [style] is set to
|
||||
/// [PaintingStyle.stroke] or [PaintingStyle.strokeAndFill]. The
|
||||
/// width is given in logical pixels measured in the direction
|
||||
/// orthogonal to the direction of the path.
|
||||
///
|
||||
/// The values null and 0.0 correspond to a hairline width.
|
||||
double strokeWidth;
|
||||
|
||||
/// The kind of finish to place on the end of lines drawn when
|
||||
/// [style] is set to [PaintingStyle.stroke] or
|
||||
/// [PaintingStyle.strokeAndFill].
|
||||
///
|
||||
/// If null, defaults to [StrokeCap.butt], i.e. no caps.
|
||||
StrokeCap strokeCap;
|
||||
|
||||
/// Whether to apply anti-aliasing to lines and images drawn on the
|
||||
/// canvas.
|
||||
///
|
||||
/// Defaults to true. The value null is treated as false.
|
||||
bool isAntiAlias = true;
|
||||
|
||||
Color color = _kDefaultPaintColor;
|
||||
static const Color _kDefaultPaintColor = const Color(0xFF000000);
|
||||
|
||||
TransferMode transferMode;
|
||||
|
||||
ColorFilter colorFilter;
|
||||
|
||||
MaskFilter maskFilter;
|
||||
|
||||
FilterQuality filterQuality;
|
||||
|
||||
Shader shader;
|
||||
|
||||
// Must match PaintFields enum in Paint.cpp.
|
||||
dynamic get _value {
|
||||
// The most common usage is a Paint with no options besides a color and
|
||||
// anti-aliasing. In this case, save time by just returning the color
|
||||
// as an int.
|
||||
if (color != null &&
|
||||
strokeWidth == null &&
|
||||
if ((style == null || style == PaintingStyle.fill) &&
|
||||
(strokeWidth == null || strokeWidth == 0.0) &&
|
||||
(strokeCap == null || strokeCap == StrokeCap.butt) &&
|
||||
isAntiAlias &&
|
||||
colorFilter == null &&
|
||||
filterQuality == null &&
|
||||
maskFilter == null &&
|
||||
shader == null &&
|
||||
style == null &&
|
||||
color != null &&
|
||||
transferMode == null &&
|
||||
strokeCap == null) {
|
||||
colorFilter == null &&
|
||||
maskFilter == null &&
|
||||
filterQuality == null &&
|
||||
shader == null) {
|
||||
return color.value;
|
||||
}
|
||||
|
||||
return [
|
||||
return <dynamic>[
|
||||
style,
|
||||
strokeWidth,
|
||||
strokeCap,
|
||||
isAntiAlias,
|
||||
color,
|
||||
colorFilter,
|
||||
filterQuality,
|
||||
maskFilter,
|
||||
shader,
|
||||
style,
|
||||
transferMode,
|
||||
strokeCap,
|
||||
colorFilter,
|
||||
maskFilter,
|
||||
filterQuality,
|
||||
shader,
|
||||
];
|
||||
}
|
||||
|
||||
String toString() {
|
||||
String result = 'Paint(color:$color';
|
||||
StringBuffer result = new StringBuffer();
|
||||
String semicolon = '';
|
||||
result.write('Paint(');
|
||||
if (style == PaintingStyle.stroke || style == PaintingStyle.strokeAndFill) {
|
||||
result.write('$style');
|
||||
if (strokeWidth != null && strokeWidth != 0.0)
|
||||
result.write(' $strokeWidth');
|
||||
else
|
||||
result.write(' hairline');
|
||||
if (strokeCap != null && strokeCap != StrokeCap.butt)
|
||||
result.write(' $strokeCap');
|
||||
semicolon = '; ';
|
||||
}
|
||||
if (isAntiAlias != true) {
|
||||
result.write('${semicolon}antialias off');
|
||||
semicolon = '; ';
|
||||
}
|
||||
if (color != _kDefaultPaintColor) {
|
||||
if (color != null)
|
||||
result.write('$semicolon$color');
|
||||
else
|
||||
result.write('${semicolon}no color');
|
||||
semicolon = '; ';
|
||||
}
|
||||
if (transferMode != null) {
|
||||
result.write('$semicolon$transferMode');
|
||||
semicolon = '; ';
|
||||
}
|
||||
if (colorFilter != null) {
|
||||
result.write('${semicolon}colorFilter: $colorFilter');
|
||||
semicolon = '; ';
|
||||
}
|
||||
if (maskFilter != null) {
|
||||
result.write('${semicolon}maskFilter: $maskFilter');
|
||||
semicolon = '; ';
|
||||
}
|
||||
if (filterQuality != null) {
|
||||
result.write('${semicolon}filterQuality: $filterQuality');
|
||||
semicolon = '; ';
|
||||
}
|
||||
if (shader != null)
|
||||
result += ', shader: $shader';
|
||||
if (colorFilter != null)
|
||||
result += ', colorFilter: $colorFilter';
|
||||
if (maskFilter != null)
|
||||
result += ', maskFilter: $maskFilter';
|
||||
result += ')';
|
||||
return result;
|
||||
result.write('${semicolon}shader: $shader');
|
||||
result.write(')');
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,10 +4,27 @@
|
||||
|
||||
part of dart_ui;
|
||||
|
||||
/// List of predefined painting styles. This list comes from Skia's
|
||||
/// SkPaint.h and the values (order) should be kept in sync.
|
||||
// List of predefined painting styles. This list comes from Skia's
|
||||
// SkPaint.h and the values (order) should be kept in sync.
|
||||
|
||||
/// Strategies for painting shapes and paths on a canvas.
|
||||
///
|
||||
/// See [Paint.style].
|
||||
enum PaintingStyle {
|
||||
/// Apply the [Paint] to the inside of the shape. For example, when
|
||||
/// applied to the [Paint.drawCircle] call, this results in a disc
|
||||
/// of the given size being painted.
|
||||
fill,
|
||||
|
||||
/// Apply the [Paint] to the edge of the shape. For example, when
|
||||
/// applied to the [Paint.drawCircle] call, this results is a hoop
|
||||
/// of the given size being painted. The line drawn on the edge will
|
||||
/// be the width given by the [Paint.strokeWidth] property.
|
||||
stroke,
|
||||
|
||||
/// Apply the [Paint] to the inside of the shape and the edge of the
|
||||
/// shape at the same time. The resulting drawing is similar to what
|
||||
/// would be achieved by inflating the shape by half the stroke
|
||||
/// width (as given by [Paint.strokeWidth]), and then using [fill].
|
||||
strokeAndFill,
|
||||
}
|
||||
|
||||
@ -4,10 +4,19 @@
|
||||
|
||||
part of dart_ui;
|
||||
|
||||
/// List of predefined color transfer modes. This list comes from Skia's
|
||||
/// SkXfermode.h and the values (order) should be kept in sync.
|
||||
/// See [https://skia.org/user/api/skpaint#SkXfermode] for how these
|
||||
/// transfer modes behave.
|
||||
// List of predefined color transfer modes. This list comes from Skia's
|
||||
// SkXfermode.h and the values (order) should be kept in sync.
|
||||
// See: https://skia.org/user/api/skpaint#SkXfermode
|
||||
|
||||
/// Algorithms to use when painting on the canvas.
|
||||
///
|
||||
/// When drawing a shape or image onto a canvas, different algorithms
|
||||
/// can be used to blend the pixels. The image below shows the effects
|
||||
/// of these modes.
|
||||
///
|
||||
/// [](https://fiddle.skia.org/c/871ab434ce53a611e5eb2b662c69d154)
|
||||
///
|
||||
/// See [Paint.transferMode].
|
||||
enum TransferMode {
|
||||
clear,
|
||||
src,
|
||||
@ -25,7 +34,8 @@ enum TransferMode {
|
||||
modulate,
|
||||
|
||||
// Following blend modes are defined in the CSS Compositing standard.
|
||||
screen, /// The last coeff mode.
|
||||
|
||||
screen, // The last coeff mode.
|
||||
|
||||
overlay,
|
||||
darken,
|
||||
@ -36,7 +46,7 @@ enum TransferMode {
|
||||
softLight,
|
||||
difference,
|
||||
exclusion,
|
||||
multiply, /// The last separable mode.
|
||||
multiply, // The last separable mode.
|
||||
|
||||
hue,
|
||||
saturation,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user