mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-03-14 00:39:57 -04:00
Optimise handling and setting of fill and stroke styles.
Handle setting of fillColor and strokeColor in Item#_setStyles() instead of the various #draw() methods, directly access internal styles instead of using accessor calls and fix PointText#draw().
This commit is contained in:
parent
ea0eaf04ea
commit
cc26fdc5d1
4 changed files with 66 additions and 68 deletions
src
|
@ -2373,15 +2373,28 @@ function(name) {
|
|||
* e.g. PointText.
|
||||
*/
|
||||
_setStyles: function(ctx) {
|
||||
// We can access internal properties since we're only using this on
|
||||
// items without children, where styles would be merged.
|
||||
var style = this._style,
|
||||
width = style.getStrokeWidth(),
|
||||
join = style.getStrokeJoin(),
|
||||
cap = style.getStrokeCap(),
|
||||
limit = style.getMiterLimit();
|
||||
width = style._strokeWidth,
|
||||
join = style._strokeJoin,
|
||||
cap = style._strokeCap,
|
||||
limit = style._miterLimit,
|
||||
fillColor = style._fillColor,
|
||||
strokeColor = style._strokeColor;
|
||||
if (width != null) ctx.lineWidth = width;
|
||||
if (join) ctx.lineJoin = join;
|
||||
if (cap) ctx.lineCap = cap;
|
||||
if (limit) ctx.miterLimit = limit;
|
||||
// Always set fillStyle and strokeStyle, so the code calling
|
||||
// #_setStyles() can check them to see if we need to stroke / fill.
|
||||
ctx.fillStyle = fillColor ? fillColor.getCanvasStyle(ctx) : null;
|
||||
ctx.strokeStyle = strokeColor ? strokeColor.getCanvasStyle(ctx) : null;
|
||||
// If the item only defines a strokeColor or a fillColor, draw it
|
||||
// directly with the globalAlpha set, otherwise we will do it later when
|
||||
// we composite the temporary canvas.
|
||||
if (!fillColor || !strokeColor)
|
||||
ctx.globalAlpha = this._opacity;
|
||||
},
|
||||
|
||||
statics: {
|
||||
|
@ -2414,8 +2427,8 @@ function(name) {
|
|||
// first, since otherwise their stroke is drawn half transparent
|
||||
// over their fill.
|
||||
if (item._blendMode !== 'normal' || item._opacity < 1
|
||||
&& !(item._segments && (!item.getFillColor()
|
||||
|| !item.getStrokeColor()))) {
|
||||
&& !(item._segments
|
||||
&& (!item.getFillColor() || !item.getStrokeColor()))) {
|
||||
var bounds = item.getStrokeBounds();
|
||||
if (!bounds.width || !bounds.height)
|
||||
return;
|
||||
|
|
|
@ -85,27 +85,20 @@ var CompoundPath = this.CompoundPath = PathItem.extend(/** @lends CompoundPath#
|
|||
},
|
||||
|
||||
draw: function(ctx, param) {
|
||||
var l = this._children.length;
|
||||
var children = this._children;
|
||||
// Return early if the compound path doesn't have any children:
|
||||
if (l == 0) {
|
||||
if (children.length == 0)
|
||||
return;
|
||||
}
|
||||
var firstChild = this._children[0];
|
||||
var firstChild = children[0];
|
||||
ctx.beginPath();
|
||||
param.compound = true;
|
||||
for (var i = 0; i < l; i++)
|
||||
Item.draw(this._children[i], ctx, param);
|
||||
for (var i = 0, l = children.length; i < l; i++)
|
||||
Item.draw(children[i], ctx, param);
|
||||
firstChild._setStyles(ctx);
|
||||
var fillColor = firstChild.getFillColor(),
|
||||
strokeColor = firstChild.getStrokeColor();
|
||||
if (fillColor) {
|
||||
ctx.fillStyle = fillColor.getCanvasStyle(ctx);
|
||||
if (ctx.fillStyle)
|
||||
ctx.fill();
|
||||
}
|
||||
if (strokeColor) {
|
||||
ctx.strokeStyle = strokeColor.getCanvasStyle(ctx);
|
||||
if (ctx.strokeStyle)
|
||||
ctx.stroke();
|
||||
}
|
||||
param.compound = false;
|
||||
}
|
||||
}, new function() { // Injection scope for PostScript-like drawing functions
|
||||
|
|
|
@ -211,9 +211,11 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
for (var i = 0, l = this._segments.length; i < l; i++) {
|
||||
this._segments[i]._transformCoordinates(matrix, coords, true);
|
||||
}
|
||||
// TODO: Can't we access _style._fillColor, as we do in strokeBounds?
|
||||
var fillColor = this.getFillColor(),
|
||||
strokeColor = this.getStrokeColor();
|
||||
// See #draw() for an explanation of why we can access _style properties
|
||||
// directly here:
|
||||
var style = this._style,
|
||||
fillColor = style._fillColor,
|
||||
strokeColor = style._strokeColor;
|
||||
// Try calling transform on colors in case they are GradientColors.
|
||||
if (fillColor && fillColor.transform)
|
||||
fillColor.transform(matrix);
|
||||
|
@ -1232,10 +1234,12 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
},
|
||||
|
||||
_hitTest: function(point, options, matrix) {
|
||||
// TODO: Can't we access _style._strokeColor, as we do in strokeBounds?
|
||||
var tolerance = options.tolerance || 0,
|
||||
radius = (options.stroke && this.getStrokeColor()
|
||||
? this.getStrokeWidth() / 2 : 0) + tolerance,
|
||||
// See #draw() for an explanation of why we can access _style properties
|
||||
// directly here:
|
||||
var style = this._style,
|
||||
tolerance = options.tolerance || 0,
|
||||
radius = (options.stroke && style._strokeColor
|
||||
? style._strokeWidth / 2 : 0) + tolerance,
|
||||
loc,
|
||||
res;
|
||||
// If we're asked to query for segments, ends or handles, do all that
|
||||
|
@ -1272,7 +1276,7 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
// in some cases. Simply skip fill query if we already have a matching
|
||||
// stroke.
|
||||
if (!(loc && loc._distance <= radius) && options.fill
|
||||
&& this.getFillColor() && this.contains(point, matrix))
|
||||
&& style._fillColor && this.contains(point, matrix))
|
||||
return new HitResult('fill', this);
|
||||
// Now query stroke if we haven't already
|
||||
if (!loc && options.stroke && radius > 0)
|
||||
|
@ -1390,13 +1394,17 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
if (!param.compound)
|
||||
ctx.beginPath();
|
||||
|
||||
// TODO: Can't we access _style._strokeColor, as we do in
|
||||
// strokeBounds?
|
||||
var fillColor = this.getFillColor(),
|
||||
strokeColor = this.getStrokeColor(),
|
||||
dashArray = this.getDashArray() || [], // TODO: Always defined?
|
||||
hasDash = !!dashArray.length;
|
||||
// We can access styles directly on the internal _styles object,
|
||||
// since Path items do not have children, thus do not need style
|
||||
// accessors for merged styles.
|
||||
var style = this._style,
|
||||
fillColor = style._fillColor,
|
||||
strokeColor = style._strokeColor,
|
||||
dashArray = style._dashArray,
|
||||
hasDash = strokeColor && dashArray && dashArray.length;
|
||||
|
||||
// Prepare the canvas path if we have any situation that requires it
|
||||
// to be defined.
|
||||
if (param.compound || param.selection || this._clipMask || fillColor
|
||||
|| strokeColor && !hasDash) {
|
||||
drawSegments(ctx, this);
|
||||
|
@ -1414,23 +1422,14 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
// or stroke, there is no need to continue.
|
||||
ctx.save();
|
||||
this._setStyles(ctx);
|
||||
// If the path only defines a strokeColor or a fillColor,
|
||||
// draw it directly with the globalAlpha set, otherwise
|
||||
// we will do it later when we composite the temporary
|
||||
// canvas.
|
||||
if (!fillColor || !strokeColor)
|
||||
ctx.globalAlpha = this._opacity;
|
||||
if (fillColor) {
|
||||
ctx.fillStyle = fillColor.getCanvasStyle(ctx);
|
||||
if (fillColor)
|
||||
ctx.fill();
|
||||
}
|
||||
if (strokeColor) {
|
||||
ctx.strokeStyle = strokeColor.getCanvasStyle(ctx);
|
||||
if (hasDash) {
|
||||
// We cannot use the path created by drawSegments above
|
||||
// Use CurveFlatteners to draw dashed paths:
|
||||
ctx.beginPath();
|
||||
drawDashes(ctx, this, dashArray, this.getDashOffset());
|
||||
drawDashes(ctx, this, dashArray, style._dashOffset);
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
|
@ -1894,18 +1893,20 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
* Returns the bounding rectangle of the item including stroke width.
|
||||
*/
|
||||
function getStrokeBounds(matrix) {
|
||||
// TODO: Should we access this.getStrokeColor, as we do in _transform?
|
||||
// See #draw() for an explanation of why we can access _style
|
||||
// properties directly here:
|
||||
var style = this._style;
|
||||
// TODO: Find a way to reuse 'bounds' cache instead?
|
||||
if (!this._style._strokeColor || !this._style._strokeWidth)
|
||||
if (!style._strokeColor || !style._strokeWidth)
|
||||
return getBounds.call(this, matrix);
|
||||
var width = this.getStrokeWidth(),
|
||||
var width = style._strokeWidth,
|
||||
radius = width / 2,
|
||||
padding = getPenPadding(radius, matrix),
|
||||
join = this.getStrokeJoin(),
|
||||
cap = this.getStrokeCap(),
|
||||
join = style._strokeJoin,
|
||||
cap = style._strokeCap,
|
||||
// miter is relative to width. Divide it by 2 since we're
|
||||
// measuring half the distance below
|
||||
miter = this.getMiterLimit() * width / 2,
|
||||
miter = style._miterLimit * width / 2,
|
||||
segments = this._segments,
|
||||
length = segments.length,
|
||||
// It seems to be compatible with Ai we need to pass pen padding
|
||||
|
@ -2032,10 +2033,11 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
// Delegate to handleBounds, but pass on radius values for stroke and
|
||||
// joins. Hanlde miter joins specially, by passing the largets radius
|
||||
// possible.
|
||||
var width = this.getStrokeWidth();
|
||||
var style = this._style,
|
||||
width = style._strokeWidth;
|
||||
return getHandleBounds.call(this, matrix, width,
|
||||
this.getStrokeJoin() == 'miter'
|
||||
? width * this.getMiterLimit()
|
||||
style._strokeJoin == 'miter'
|
||||
? width * style._miterLimit
|
||||
: width);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,28 +71,18 @@ var PointText = this.PointText = TextItem.extend(/** @lends PointText# */{
|
|||
draw: function(ctx) {
|
||||
if (!this._content)
|
||||
return;
|
||||
ctx.save();
|
||||
this._setStyles(ctx);
|
||||
ctx.font = this.getFontSize() + 'px ' + this.getFont();
|
||||
ctx.textAlign = this.getJustification();
|
||||
this._matrix.applyToContext(ctx);
|
||||
var fillColor = this.getFillColor(),
|
||||
strokeColor = this.getStrokeColor(),
|
||||
leading = this.getLeading();
|
||||
if (!fillColor || !strokeColor)
|
||||
ctx.globalAlpha = this._opacity;
|
||||
if (fillColor)
|
||||
ctx.fillStyle = fillColor.getCanvasStyle(ctx);
|
||||
if (strokeColor)
|
||||
ctx.strokeStyle = strokeColor.getCanvasStyle(ctx);
|
||||
var leading = this.getLeading();
|
||||
for (var i = 0, l = this._lines.length; i < l; i++) {
|
||||
var line = this._lines[i];
|
||||
if (fillColor)
|
||||
if (ctx.fillStyle)
|
||||
ctx.fillText(line, 0, 0);
|
||||
if (strokeColor)
|
||||
if (ctx.strokeStyle)
|
||||
ctx.strokeText(line, 0, 0);
|
||||
ctx.translate(0, leading);
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
}, new function() {
|
||||
var context = null;
|
||||
|
|
Loading…
Reference in a new issue