]> git.parisson.com Git - pdf.js.git/commitdiff
Add setFillColorN_IR by implementing new TilingPatternIR
authorJulian Viereck <julian.viereck@gmail.com>
Wed, 7 Sep 2011 18:30:35 +0000 (11:30 -0700)
committerJulian Viereck <julian.viereck@gmail.com>
Thu, 15 Sep 2011 15:21:23 +0000 (08:21 -0700)
pdf.js

diff --git a/pdf.js b/pdf.js
index e2aece9b74705688337b4ee22fb498fdeaa7e255..2ea59079f426f5750b09568a7464f6778f596abf 100644 (file)
--- a/pdf.js
+++ b/pdf.js
@@ -4230,10 +4230,18 @@ var PartialEvaluator = (function() {
               if (pattern) {
                 var dict = IsStream(pattern) ? pattern.dict : pattern;
                 var typeNum = dict.get('PatternType');
+
+                // Type1 is TilingPattern, Type2 is ShadingPattern.
                 if (typeNum == 1) {
-                  patternName.code = this.evaluate(pattern, xref,
-                                                   dict.get('Resources'),
-                                                   fonts);
+                  // Create an IR of the pattern code.
+                  var codeIR = this.evalRaw(pattern, xref,
+                                    dict.get('Resources'), fonts);
+                  
+                  fn = "setFillColorN_IR";
+                  args = TilingPattern.getIR(codeIR, dict);
+
+                  //patternName.code = this.evalRaw(pattern, xref,
+                  //    dict.get('Resources'), fonts);
                 }
               }
             }
@@ -4884,6 +4892,13 @@ var CanvasGraphics = (function() {
       this.xref = savedXref;
     },
 
+    executeIR: function(codeIR) {
+      var argsArray = codeIR.argsArray;
+      var fnArray =   codeIR.fnArray;
+      for (var i = 0, length = argsArray.length; i < length; i++)
+        this[fnArray[i]].apply(this, argsArray[i]);
+    },
+
     endDrawing: function() {
       this.ctx.restore();
     },
@@ -5272,6 +5287,36 @@ var CanvasGraphics = (function() {
         this.setFillColor.apply(this, arguments);
       }
     },
+    setFillColorN_IR: function(/*...*/) {
+      var cs = this.current.fillColorSpace;
+
+      if (cs.name == 'Pattern') {
+        var IR = arguments;
+        if (IR[0] == "TilingPatternIR") {
+          // First, build the `color` var like it's done in the
+          // Pattern.prototype.parse function.
+          var base = cs.base;
+          var color;
+          if (base) {
+            var baseComps = base.numComps;
+
+            color = [];
+            for (var i = 0; i < baseComps; ++i)
+              color.push(args[i]);
+
+            color = base.getRgb(color);
+          }
+
+          // Build the pattern based on the IR data.
+          var pattern = new TilingPatternIR(IR, color, this.ctx);
+        } else {
+          throw "Unkown IR type";
+        }
+        this.current.fillColor = pattern;
+      } else {
+        this.setFillColor.apply(this, arguments);
+      }
+    },
     setStrokeGray: function(gray) {
       this.setStrokeRGBColor(gray, gray, gray);
     },
@@ -6332,20 +6377,119 @@ var RadialAxialShading = (function() {
   return constructor;
 })();
 
+var TilingPatternIR = (function() {
+  var PAINT_TYPE_COLORED = 1, PAINT_TYPE_UNCOLORED = 2;
+
+  function TilingPatternIR(IR, color, ctx) {
+    // "Unfolding" the IR.
+    var codeIR = IR[1];
+    this.matrix = IR[2];
+    var bbox = IR[3];
+    var xstep = IR[4];
+    var ystep = IR[5];
+    var paintType = IR[6];
+
+    // 
+    TODO('TilingType');
+
+    this.curMatrix = ctx.mozCurrentTransform;
+    this.invMatrix = ctx.mozCurrentTransformInverse;
+    this.ctx = ctx;
+    this.type = 'Pattern';
+
+    var x0 = bbox[0], y0 = bbox[1], x1 = bbox[2], y1 = bbox[3];
+    var topLeft = [x0, y0];
+    // we want the canvas to be as large as the step size
+    var botRight = [x0 + xstep, y0 + ystep];
+
+    var width = botRight[0] - topLeft[0];
+    var height = botRight[1] - topLeft[1];
+
+    // TODO: hack to avoid OOM, we would idealy compute the tiling
+    // pattern to be only as large as the acual size in device space
+    // This could be computed with .mozCurrentTransform, but still
+    // needs to be implemented
+    while (Math.abs(width) > 512 || Math.abs(height) > 512) {
+      width = 512;
+      height = 512;
+    }
+
+    var tmpCanvas = new ScratchCanvas(width, height);
+
+    // set the new canvas element context as the graphics context
+    var tmpCtx = tmpCanvas.getContext('2d');
+    var graphics = new CanvasGraphics(tmpCtx);
+
+    switch (paintType) {
+    case PAINT_TYPE_COLORED:
+      tmpCtx.fillStyle = ctx.fillStyle;
+      tmpCtx.strokeStyle = ctx.strokeStyle;
+      break;
+    case PAINT_TYPE_UNCOLORED:
+      color = Util.makeCssRgb.apply(this, color);
+      tmpCtx.fillStyle = color;
+      tmpCtx.strokeStyle = color;
+      break;
+    default:
+      error('Unsupported paint type: ' + paintType);
+    }
+
+    var scale = [width / xstep, height / ystep];
+    this.scale = scale;
+
+    // transform coordinates to pattern space
+    var tmpTranslate = [1, 0, 0, 1, -topLeft[0], -topLeft[1]];
+    var tmpScale = [scale[0], 0, 0, scale[1], 0, 0];
+    graphics.transform.apply(graphics, tmpScale);
+    graphics.transform.apply(graphics, tmpTranslate);
+
+    if (bbox && IsArray(bbox) && 4 == bbox.length) {
+      graphics.rectangle.apply(graphics, bbox);
+      graphics.clip();
+      graphics.endPath();
+    }
+
+    graphics.executeIR(codeIR);
+
+    this.canvas = tmpCanvas;
+  }
+
+  TilingPatternIR.prototype = {
+    getPattern: function tiling_getPattern() {
+      var matrix = this.matrix;
+      var curMatrix = this.curMatrix;
+      var ctx = this.ctx;
+
+      if (curMatrix)
+        ctx.setTransform.apply(ctx, curMatrix);
+
+      if (matrix)
+        ctx.transform.apply(ctx, matrix);
+
+      var scale = this.scale;
+      ctx.scale(1 / scale[0], 1 / scale[1]);
+
+      return ctx.createPattern(this.canvas, 'repeat');
+    }
+  }
+
+  return TilingPatternIR;
+})();
+
 var TilingPattern = (function() {
   var PAINT_TYPE_COLORED = 1, PAINT_TYPE_UNCOLORED = 2;
 
-  function constructor(pattern, code, dict, color, xref, ctx) {
-      function multiply(m, tm) {
-        var a = m[0] * tm[0] + m[1] * tm[2];
-        var b = m[0] * tm[1] + m[1] * tm[3];
-        var c = m[2] * tm[0] + m[3] * tm[2];
-        var d = m[2] * tm[1] + m[3] * tm[3];
-        var e = m[4] * tm[0] + m[5] * tm[2] + tm[4];
-        var f = m[4] * tm[1] + m[5] * tm[3] + tm[5];
-        return [a, b, c, d, e, f];
-      }
+  constructor.getIR = function(codeIR, dict) {
+    var matrix = dict.get('Matrix');
+    var bbox = dict.get('BBox');
+    var xstep = dict.get('XStep');
+    var ystep = dict.get('YStep');
+    var paintType = dict.get('PaintType');
+    
+    return ["TilingPatternIR", codeIR, matrix, bbox, xstep, ystep, paintType];
+  }
 
+  function constructor(pattern, code, dict, color, xref, ctx) {
       TODO('TilingType');
 
       this.matrix = dict.get('Matrix');