Beispiel #1
0
  result.save = function () {
    var current = {
      matrix: m.create(),
      clippingEnabled: undefined,
      mask: undefined,
      strokeStyle: strokeStyle,
      fillStyle: fillStyle,
      globalAlpha: globalAlpha,
      imageSmoothingEnabled: imageSmoothingEnabled,
      lineWidth: lineWidth,
      lineCap: lineCap,
      lineJoin: lineJoin,
      miterLimit: miterLimit,
      lineDashPattern: lineDashPattern,
      lineDashOffset: lineDashOffset,
      shadowOffsetX: shadowOffsetX,
      shadowOffsetY: shadowOffsetY,
      shadowBlur: shadowBlur,
      serializedShadowColor:
        serializedShadowColor || color.serialize(shadowColor),
      globalCompositeOperation: globalCompositeOperation,
      font: font,
      textAlign: textAlign,
      textBaseline: textBaseline
    };

    vg.getMatrix(current.matrix);
    saveClippingRegion(current);

    drawingStateStack.push(current);
  };
Beispiel #2
0
Path.prototype.addVGPath = function (vgPath, transform) {
  var currentMatrix = m.create();

  this.renderPath();

  vg.getMatrix(currentMatrix);
  vg.loadMatrix(transform.m);
  vg.transformPath(this.vgPath, vgPath);
  vg.loadMatrix(currentMatrix);
};
Beispiel #3
0
      function paintShadow() {
        var mm = m.create();
        vg.getMatrix(mm);
        vg.setI(vg.VGParamType.VG_MATRIX_MODE,
                vg.VGMatrixMode.VG_MATRIX_IMAGE_USER_TO_SURFACE);
        vg.loadMatrix(mm);
        paint();

        vg.setI(vg.VGParamType.VG_MATRIX_MODE,
                vg.VGMatrixMode.VG_MATRIX_PATH_USER_TO_SURFACE);
      }
Beispiel #4
0
  textFns.loadTypeface(styles.fontInfo_, function (err, typeface) {
    var currentMatrix = m.create();

    vg.getMatrix(currentMatrix);

    self.renderPath();
    var path = textRendering.renderToPath(text, typeface, styles.fontInfo_.size);

    self.addVGPath(path, transform.vgScale(1.0, -1.0).mTranslate(x, y));

    vg.destroyPath(path);

    vg.loadMatrix(currentMatrix);
  });
Beispiel #5
0
Path.prototype.addTextOnPath = function (text, styles, transform, path, maxWidth) {
  var self = this;

  var currentMatrix = m.create();
  vg.getMatrix(currentMatrix);

  // This is the algorithm specified by
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-path-addtext
  // [...]
  // When one of the addText() and addPathByStrokingText() variants that
  // take as argument a Path object is invoked, the method must run the
  // following algorithm:

  // 1. Let target be the Path object on which the method was invoked.
  self.renderPath();
  // 2. Let path be the Path object that was provided in the method's
  //    arguments.
  path.renderPath();

  // 3. Run the text preparation algorithm, passing it text, the
  //    CanvasDrawingStyles object argument, and, if the maxWidth argument was
  //    provided, that argument. Let glyphs be the resulting array, and
  //    physical alignment be the resulting alignment value.
  var renderInfo = textRendering.prepareText(text, styles, maxWidth);
  var typeface = renderInfo.typeface;
  var size = renderInfo.fontInfo.size;

  // 4. Let width be the aggregate length of all the subpaths in path,
  //    including the distances from the last point of each closed subpath
  //    to the first point of that subpath.
  var pathNumSegments =
    vg.getParameterI(path.vgPath, vg.VGPathParamType.VG_PATH_NUM_SEGMENTS);
  var width = vg.pathLength(path.vgPath, 0, pathNumSegments);

  // 5. Define L to be a linear coordinate line for of all the subpaths in
  //    path, with additional lines drawn between the last point and the first
  //    point of each closed subpath, such that the first point of the first
  //    subpath is defined as point 0, and the last point of the last subpath,
  //    if the last subpath is not closed, or the second occurrence first
  //    point of that subpath, if it is closed, is defined as point width.
  // This looks like the way vgPointAlongPath's distance parameter works.

  // 6. Let offset be determined according to the appropriate step below:
  //    If physical alignment is left   => Let offset be zero.
  //    If physical alignment is right  => Let offset be width.
  //    If physical alignment is center => Let offset be half of width.
  var offset;
  if (renderInfo.physicalAlignment === 'left') {
    offset = 0;
  } else
  if (renderInfo.physicalAlignment === 'right') {
    offset = width;
  } else
  if (renderInfo.physicalAlignment === 'center') {
    offset = width / 2;
  }

  // 7. Move all the shapes in glyphs to the right by offset CSS pixels.
  for (var i = 0; i < renderInfo.glyphCount; i++) {
    renderInfo.glyphPositions[i].x += offset;
  }

  // 8. For each glyph glyph in the glyphs array, run these substeps:
  var pointInfo = { x: 0.0, y: 0.0, tx: 0.0, ty: 0.0 };
  var textPath =
    textRendering.transformRenderToPath(text, renderInfo,
                                        function (textPath, idx, character) {

    var glyph = typeface.characterMap[character];

    //     1. Let dx be the x-coordinate of the horizontal center of the
    //        bounding box of the shape described by glyph, in CSS pixels.
    var bbox = typeface.glyphBBoxes[glyph];
    var hCenter = (bbox.minX + (bbox.maxX - bbox.minX) / 2) * size / 65536.0;
    var dx = renderInfo.glyphPositions[idx].x + hCenter;

    //     2. If dx is negative or greater than width, skip the remainder or
    //        these substeps for this glyph.
    if (dx < 0 || dx > width) return false;

    //     3. Recast dx to coordinate spaces units in path. (This just changes
    //        the dimensionality of dx, not its numeric value.)
    // WAT !?

    //     4. Find the point p on path (or implied closing lines in path) that
    //        corresponds to the position dx on the coordinate line L.
    vg.pointAlongPath(path.vgPath, 0, pathNumSegments, dx, pointInfo);

    //     5. Let θ be the clockwise angle from the positive x-axis to the side
    //        of the line that is tangential to path at the point p that is
    //        going in the same direction as the line at point p.
    var theta = Math.atan2(pointInfo.ty, pointInfo.tx);

    //     6. Rotate the shape described by glyph clockwise by θ about the
    //        point that is at the dx coordinate horizontally and the zero
    //        coordinate vertically.
    //     7. Let (x, y) be the coordinate of the point p.
    //     8. Move the shape described by glyph to the right by x and down by
    //        y.
    // This operations must be run in reverse order.

    vg.translate(pointInfo.x, pointInfo.y);
    vg.rotate(theta * 180 / Math.PI);
    vg.translate(-hCenter, renderInfo.anchor.y);
    vg.scale(size * renderInfo.scaleX, -size);

    //     9. Let glyph subpaths be a list of subpaths describing the shape
    //        given in glyph, with each CSS pixel in the coordinate space of
    //        glyph mapped to one coordinate space unit in glyph subpaths.
    //        Subpaths in glyph subpaths must wind clockwise, regardless of
    //        how the user agent's font subsystem renders fonts and
    //        regardless of how the fonts themselves are defined.
    // Nothing to do here (maybe?)

    //    10. If the method is addPathByStrokingText(), replace glyph
    //        subpaths by the result of tracing glyph subpaths, using the
    //        CanvasDrawingStyles object argument for the line styles.
    // Nothing to do here (no support for addPathByStrokingText for now)

    //    11. Transform all the coordinates and lines in glyph subpaths by
    //        the transformation matrix transform, if it is not null.
    // See 9. below

    //    12. Let (xfinal, yfinal) be the last point in the last subpath of
    //        glyph subpaths. (This coordinate is only used if this is the
    //        last glyph processed.)
    // TODO Complement loading so that this point is stored

    //    13. Add all the subpaths in glyph subpaths to target.
    vg.transformPath(textPath, typeface.glyphs[glyph]);
  });

  // 9. Create a new subpath in the Path object with (xfinal, yfinal) as the
  //    only point in the subpath.
  // TODO Complement loading so that this point is stored (same as 8.12)

  // self.addVGPath(textPath, transform.vgScale(1.0, -1.0));
  // This is the actual 8.11 step.
  self.addVGPath(textPath, transform);
  vg.destroyPath(path);

  vg.loadMatrix(currentMatrix);
};
Beispiel #6
0
  function dropShadow(paintFn) {
    var success;

    var saveBlendMode = vg.getI(vg.VGParamType.VG_BLEND_MODE);

    vg.getMatrix(shadowTransform);

    success = vg.egl.makeCurrent(shadowSurface, shadowContext);

    vg.loadMatrix(shadowTransform);

    vg.clear(0, 0, width, height);

    vg.translate(shadowOffsetX, shadowOffsetY);
    paintFn();
    vg.translate(-shadowOffsetX, -shadowOffsetY);

    vg.setI(vg.VGParamType.VG_BLEND_MODE, vg.VGBlendMode.VG_BLEND_SRC_IN);
    vg.setParameterI(shadowPaint, vg.VGPaintParamType.VG_PAINT_TYPE,
                                  vg.VGPaintType.VG_PAINT_TYPE_COLOR);
    vg.setParameterFV(shadowPaint, vg.VGPaintParamType.VG_PAINT_COLOR,
                                   shadowColor);
    vg.setPaint(shadowPaint, vg.VGPaintMode.VG_FILL_PATH);

    vg.getMatrix(shadowTransform);
    vg.loadIdentity();


    var vgPath = vg.createPath(vg.VG_PATH_FORMAT_STANDARD,
                               vg.VGPathDatatype.VG_PATH_DATATYPE_F,
                               1.0 /* scale */ , 0.0 /* bias */,
                               5 /* segCapacityHint */,
                               5 /* coordCapacityHint */,
                               vg.VGPathCapabilities.VG_PATH_CAPABILITY_APPEND_TO);

    vg.vgu.rect(vgPath, 0, 0, width, height);
    vg.drawPath(vgPath, vg.VGPaintMode.VG_FILL_PATH);
    vg.destroyPath(vgPath);

    vg.loadMatrix(shadowTransform);

    vg.setI(vg.VGParamType.VG_BLEND_MODE, vg.VGBlendMode.VG_BLEND_SRC_OVER);

    if (shadowBlur !== 0) {
      var sigma = shadowBlur / 2;
      vg.gaussianBlur(shadowDstImage, shadowSrcImage,
                      sigma, sigma,
                      vg.VGTilingMode.VG_TILE_PAD);
    }

    success = vg.egl.makeCurrent(vg.screen.surface, vg.screen.context);

    vg.setI(vg.VGParamType.VG_BLEND_MODE, vg.VGBlendMode.VG_BLEND_SRC_OVER);

    vg.getMatrix(shadowTransform);
    vg.loadIdentity();
    vg.drawImage(shadowBlur !== 0 ? shadowDstImage : shadowSrcImage);
    vg.loadMatrix(shadowTransform);

    vg.setI(vg.VGParamType.VG_BLEND_MODE, saveBlendMode);
  }