From e94c923f5c2f7b66a6c247f8ca570392645c6576 Mon Sep 17 00:00:00 2001
From: Andrea Canciani <ranma42@gmail.com>
Date: Wed, 19 Jan 2011 09:59:27 +0100
Subject: [PATCH 1/3] Abstract GfxSimpleShading

Axial and radial shadings can share most of the code. This makes it
easier to reuse code, for example color computation and caching.
---
 poppler/GfxState.cc |  135 +++++++++++++++++++++-----------------------------
 poppler/GfxState.h  |   57 ++++++++++++---------
 2 files changed, 89 insertions(+), 103 deletions(-)

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 78ac5a8..6255c32 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -2708,22 +2708,17 @@ void GfxFunctionShading::getColor(double x, double y, GfxColor *color) {
 }
 
 //------------------------------------------------------------------------
-// GfxAxialShading
+// GfxUnivariateShading
 //------------------------------------------------------------------------
 
-GfxAxialShading::GfxAxialShading(double x0A, double y0A,
-				 double x1A, double y1A,
-				 double t0A, double t1A,
-				 Function **funcsA, int nFuncsA,
-				 GBool extend0A, GBool extend1A):
-  GfxShading(2)
+GfxUnivariateShading::GfxUnivariateShading(int typeA,
+					   double t0A, double t1A,
+					   Function **funcsA, int nFuncsA,
+					   GBool extend0A, GBool extend1A):
+  GfxShading(typeA)
 {
   int i;
 
-  x0 = x0A;
-  y0 = y0A;
-  x1 = x1A;
-  y1 = y1A;
   t0 = t0A;
   t1 = t1A;
   nFuncs = nFuncsA;
@@ -2734,15 +2729,11 @@ GfxAxialShading::GfxAxialShading(double x0A, double y0A,
   extend1 = extend1A;
 }
 
-GfxAxialShading::GfxAxialShading(GfxAxialShading *shading):
+GfxUnivariateShading::GfxUnivariateShading(GfxUnivariateShading *shading):
   GfxShading(shading)
 {
   int i;
 
-  x0 = shading->x0;
-  y0 = shading->y0;
-  x1 = shading->x1;
-  y1 = shading->y1;
   t0 = shading->t0;
   t1 = shading->t1;
   nFuncs = shading->nFuncs;
@@ -2753,7 +2744,7 @@ GfxAxialShading::GfxAxialShading(GfxAxialShading *shading):
   extend1 = shading->extend1;
 }
 
-GfxAxialShading::~GfxAxialShading() {
+GfxUnivariateShading::~GfxUnivariateShading() {
   int i;
 
   for (i = 0; i < nFuncs; ++i) {
@@ -2761,6 +2752,53 @@ GfxAxialShading::~GfxAxialShading() {
   }
 }
 
+void GfxUnivariateShading::getColor(double t, GfxColor *color) {
+  double out[gfxColorMaxComps];
+  int i;
+
+  // NB: there can be one function with n outputs or n functions with
+  // one output each (where n = number of color components)
+  for (i = 0; i < gfxColorMaxComps; ++i) {
+    out[i] = 0;
+  }
+  for (i = 0; i < nFuncs; ++i) {
+    funcs[i]->transform(&t, &out[i]);
+  }
+  for (i = 0; i < gfxColorMaxComps; ++i) {
+    color->c[i] = dblToCol(out[i]);
+  }
+}
+
+
+//------------------------------------------------------------------------
+// GfxAxialShading
+//------------------------------------------------------------------------
+
+GfxAxialShading::GfxAxialShading(double x0A, double y0A,
+				 double x1A, double y1A,
+				 double t0A, double t1A,
+				 Function **funcsA, int nFuncsA,
+				 GBool extend0A, GBool extend1A):
+  GfxUnivariateShading(2, t0A, t1A, funcsA, nFuncsA, extend0A, extend1A)
+{
+  x0 = x0A;
+  y0 = y0A;
+  x1 = x1A;
+  y1 = y1A;
+}
+
+GfxAxialShading::GfxAxialShading(GfxAxialShading *shading):
+  GfxUnivariateShading(shading)
+{
+  x0 = shading->x0;
+  y0 = shading->y0;
+  x1 = shading->x1;
+  y1 = shading->y1;
+}
+
+GfxAxialShading::~GfxAxialShading() {
+}
+
 GfxAxialShading *GfxAxialShading::parse(Dict *dict, Gfx *gfx) {
   GfxAxialShading *shading;
   double x0A, y0A, x1A, y1A;
@@ -2862,23 +2900,6 @@ GfxShading *GfxAxialShading::copy() {
   return new GfxAxialShading(this);
 }
 
-void GfxAxialShading::getColor(double t, GfxColor *color) {
-  double out[gfxColorMaxComps];
-  int i;
-
-  // NB: there can be one function with n outputs or n functions with
-  // one output each (where n = number of color components)
-  for (i = 0; i < gfxColorMaxComps; ++i) {
-    out[i] = 0;
-  }
-  for (i = 0; i < nFuncs; ++i) {
-    funcs[i]->transform(&t, &out[i]);
-  }
-  for (i = 0; i < gfxColorMaxComps; ++i) {
-    color->c[i] = dblToCol(out[i]);
-  }
-}
-
 //------------------------------------------------------------------------
 // GfxRadialShading
 //------------------------------------------------------------------------
@@ -2888,53 +2909,28 @@ GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A,
 				   double t0A, double t1A,
 				   Function **funcsA, int nFuncsA,
 				   GBool extend0A, GBool extend1A):
-  GfxShading(3)
+  GfxUnivariateShading(3, t0A, t1A, funcsA, nFuncsA, extend0A, extend1A)
 {
-  int i;
-
   x0 = x0A;
   y0 = y0A;
   r0 = r0A;
   x1 = x1A;
   y1 = y1A;
   r1 = r1A;
-  t0 = t0A;
-  t1 = t1A;
-  nFuncs = nFuncsA;
-  for (i = 0; i < nFuncs; ++i) {
-    funcs[i] = funcsA[i];
-  }
-  extend0 = extend0A;
-  extend1 = extend1A;
 }
 
 GfxRadialShading::GfxRadialShading(GfxRadialShading *shading):
-  GfxShading(shading)
+  GfxUnivariateShading(shading)
 {
-  int i;
-
   x0 = shading->x0;
   y0 = shading->y0;
   r0 = shading->r0;
   x1 = shading->x1;
   y1 = shading->y1;
   r1 = shading->r1;
-  t0 = shading->t0;
-  t1 = shading->t1;
-  nFuncs = shading->nFuncs;
-  for (i = 0; i < nFuncs; ++i) {
-    funcs[i] = shading->funcs[i]->copy();
-  }
-  extend0 = shading->extend0;
-  extend1 = shading->extend1;
 }
 
 GfxRadialShading::~GfxRadialShading() {
-  int i;
-
-  for (i = 0; i < nFuncs; ++i) {
-    delete funcs[i];
-  }
 }
 
 GfxRadialShading *GfxRadialShading::parse(Dict *dict, Gfx *gfx) {
@@ -3030,23 +3026,6 @@ GfxShading *GfxRadialShading::copy() {
   return new GfxRadialShading(this);
 }
 
-void GfxRadialShading::getColor(double t, GfxColor *color) {
-  double out[gfxColorMaxComps];
-  int i;
-
-  // NB: there can be one function with n outputs or n functions with
-  // one output each (where n = number of color components)
-  for (i = 0; i < gfxColorMaxComps; ++i) {
-    out[i] = 0;
-  }
-  for (i = 0; i < nFuncs; ++i) {
-    funcs[i]->transform(&t, &out[i]);
-  }
-  for (i = 0; i < gfxColorMaxComps; ++i) {
-    color->c[i] = dblToCol(out[i]);
-  }
-}
-
 //------------------------------------------------------------------------
 // GfxShadingBitBuf
 //------------------------------------------------------------------------
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index b425b4a..e001871 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -746,12 +746,41 @@ protected:
 };
 
 //------------------------------------------------------------------------
+// GfxUnivariateShading
+//------------------------------------------------------------------------
+
+class GfxUnivariateShading: public GfxShading {
+public:
+
+  GfxUnivariateShading(int typeA,
+		       double t0A, double t1A,
+		       Function **funcsA, int nFuncsA,
+		       GBool extend0A, GBool extend1A);
+  GfxUnivariateShading(GfxUnivariateShading *shading);
+  virtual ~GfxUnivariateShading();
+
+  double getDomain0() { return t0; }
+  double getDomain1() { return t1; }
+  GBool getExtend0() { return extend0; }
+  GBool getExtend1() { return extend1; }
+  int getNFuncs() { return nFuncs; }
+  Function *getFunc(int i) { return funcs[i]; }
+  void getColor(double t, GfxColor *color);
+
+private:
+
+  double t0, t1;
+  Function *funcs[gfxColorMaxComps];
+  int nFuncs;
+  GBool extend0, extend1;
+};
+
+//------------------------------------------------------------------------
 // GfxFunctionShading
 //------------------------------------------------------------------------
 
 class GfxFunctionShading: public GfxShading {
 public:
-
   GfxFunctionShading(double x0A, double y0A,
 		     double x1A, double y1A,
 		     double *matrixA,
@@ -782,7 +811,7 @@ private:
 // GfxAxialShading
 //------------------------------------------------------------------------
 
-class GfxAxialShading: public GfxShading {
+class GfxAxialShading: public GfxUnivariateShading {
 public:
 
   GfxAxialShading(double x0A, double y0A,
@@ -799,28 +828,17 @@ public:
 
   void getCoords(double *x0A, double *y0A, double *x1A, double *y1A)
     { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
-  double getDomain0() { return t0; }
-  double getDomain1() { return t1; }
-  GBool getExtend0() { return extend0; }
-  GBool getExtend1() { return extend1; }
-  int getNFuncs() { return nFuncs; }
-  Function *getFunc(int i) { return funcs[i]; }
-  void getColor(double t, GfxColor *color);
 
 private:
 
   double x0, y0, x1, y1;
-  double t0, t1;
-  Function *funcs[gfxColorMaxComps];
-  int nFuncs;
-  GBool extend0, extend1;
 };
 
 //------------------------------------------------------------------------
 // GfxRadialShading
 //------------------------------------------------------------------------
 
-class GfxRadialShading: public GfxShading {
+class GfxRadialShading: public GfxUnivariateShading {
 public:
 
   GfxRadialShading(double x0A, double y0A, double r0A,
@@ -838,21 +856,10 @@ public:
   void getCoords(double *x0A, double *y0A, double *r0A,
 		 double *x1A, double *y1A, double *r1A)
     { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; }
-  double getDomain0() { return t0; }
-  double getDomain1() { return t1; }
-  GBool getExtend0() { return extend0; }
-  GBool getExtend1() { return extend1; }
-  int getNFuncs() { return nFuncs; }
-  Function *getFunc(int i) { return funcs[i]; }
-  void getColor(double t, GfxColor *color);
 
 private:
 
   double x0, y0, r0, x1, y1, r1;
-  double t0, t1;
-  Function *funcs[gfxColorMaxComps];
-  int nFuncs;
-  GBool extend0, extend1;
 };
 
 //------------------------------------------------------------------------
-- 
1.7.0.4

