| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 | /** * Sub-pixel optimize for canvas rendering, prevent from blur * when rendering a thin vertical/horizontal line. */var round = Math.round;/** * Sub pixel optimize line for canvas * * @param {Object} outputShape The modification will be performed on `outputShape`. *                 `outputShape` and `inputShape` can be the same object. *                 `outputShape` object can be used repeatly, because all of *                 the `x1`, `x2`, `y1`, `y2` will be assigned in this method. * @param {Object} [inputShape] * @param {number} [inputShape.x1] * @param {number} [inputShape.y1] * @param {number} [inputShape.x2] * @param {number} [inputShape.y2] * @param {Object} [style] * @param {number} [style.lineWidth] If `null`/`undefined`/`0`, do not optimize. */function subPixelOptimizeLine(outputShape, inputShape, style) {  if (!inputShape) {    return;  }  var x1 = inputShape.x1;  var x2 = inputShape.x2;  var y1 = inputShape.y1;  var y2 = inputShape.y2;  outputShape.x1 = x1;  outputShape.x2 = x2;  outputShape.y1 = y1;  outputShape.y2 = y2;  var lineWidth = style && style.lineWidth;  if (!lineWidth) {    return;  }  if (round(x1 * 2) === round(x2 * 2)) {    outputShape.x1 = outputShape.x2 = subPixelOptimize(x1, lineWidth, true);  }  if (round(y1 * 2) === round(y2 * 2)) {    outputShape.y1 = outputShape.y2 = subPixelOptimize(y1, lineWidth, true);  }}/** * Sub pixel optimize rect for canvas * * @param {Object} outputShape The modification will be performed on `outputShape`. *                 `outputShape` and `inputShape` can be the same object. *                 `outputShape` object can be used repeatly, because all of *                 the `x`, `y`, `width`, `height` will be assigned in this method. * @param {Object} [inputShape] * @param {number} [inputShape.x] * @param {number} [inputShape.y] * @param {number} [inputShape.width] * @param {number} [inputShape.height] * @param {Object} [style] * @param {number} [style.lineWidth] If `null`/`undefined`/`0`, do not optimize. */function subPixelOptimizeRect(outputShape, inputShape, style) {  if (!inputShape) {    return;  }  var originX = inputShape.x;  var originY = inputShape.y;  var originWidth = inputShape.width;  var originHeight = inputShape.height;  outputShape.x = originX;  outputShape.y = originY;  outputShape.width = originWidth;  outputShape.height = originHeight;  var lineWidth = style && style.lineWidth;  if (!lineWidth) {    return;  }  outputShape.x = subPixelOptimize(originX, lineWidth, true);  outputShape.y = subPixelOptimize(originY, lineWidth, true);  outputShape.width = Math.max(subPixelOptimize(originX + originWidth, lineWidth, false) - outputShape.x, originWidth === 0 ? 0 : 1);  outputShape.height = Math.max(subPixelOptimize(originY + originHeight, lineWidth, false) - outputShape.y, originHeight === 0 ? 0 : 1);}/** * Sub pixel optimize for canvas * * @param {number} position Coordinate, such as x, y * @param {number} lineWidth If `null`/`undefined`/`0`, do not optimize. * @param {boolean=} positiveOrNegative Default false (negative). * @return {number} Optimized position. */function subPixelOptimize(position, lineWidth, positiveOrNegative) {  if (!lineWidth) {    return position;  } // Assure that (position + lineWidth / 2) is near integer edge,  // otherwise line will be fuzzy in canvas.  var doubledPosition = round(position * 2);  return (doubledPosition + round(lineWidth)) % 2 === 0 ? doubledPosition / 2 : (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2;}exports.subPixelOptimizeLine = subPixelOptimizeLine;exports.subPixelOptimizeRect = subPixelOptimizeRect;exports.subPixelOptimize = subPixelOptimize;
 |