diff --git a/ChangeLog b/ChangeLog index 1e11899718022e683a2b72f2c50130cd9ad26be5..fdd6ac75495126decc9da8d3ba604a57c8c5a1fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-09-20 Albert Astals Cid + * splash/SplashXPathScanner.cc: Merge from xpdf 3.01 + * splash/SplashScreen.[cc|h]: Merge from xpdf 3.01 + 2005-10-05 Kristian Høgsberg * glib/poppler-page.cc (poppler_page_render_to_ps): Fix another diff --git a/splash/SplashScreen.cc b/splash/SplashScreen.cc index f6fcaaec2af80199c1016107b818237bc17876f3..221296fd6d268fade0f83a38b38e940de6bdccb7 100644 --- a/splash/SplashScreen.cc +++ b/splash/SplashScreen.cc @@ -10,6 +10,7 @@ #pragma implementation #endif +#include #include "goo/gmem.h" #include "SplashMath.h" #include "SplashScreen.h" @@ -23,85 +24,118 @@ // Gamma correction (gamma = 1 / 1.33) is also computed here. SplashScreen::SplashScreen(int sizeA) { SplashCoord *dist; - SplashCoord u, v, d; - int x, y, x1, y1, i; + SplashCoord u, v, d, val; + int size2, x, y, x1, y1, i; - size = sizeA >> 1; - if (size < 1) { - size = 1; + size2 = sizeA >> 1; + if (size2 < 1) { + size2 = 1; } + size = size2 << 1; // initialize the threshold matrix - mat = (SplashCoord *)gmallocn(2 * size * size, sizeof(SplashCoord)); - for (y = 0; y < 2 * size; ++y) { + mat = (SplashCoord *)gmallocn(size * size, sizeof(SplashCoord)); + for (y = 0; y < size; ++y) { for (x = 0; x < size; ++x) { mat[y * size + x] = -1; } } // build the distance matrix - dist = (SplashCoord *)gmallocn(2 * size * size, sizeof(SplashCoord)); - for (y = 0; y < size; ++y) { - for (x = 0; x < size; ++x) { - if (x + y < size - 1) { - u = (SplashCoord)x + 0.5 - 0; //~ (-0.5); + dist = (SplashCoord *)gmallocn(size * size2, sizeof(SplashCoord)); + for (y = 0; y < size2; ++y) { + for (x = 0; x < size2; ++x) { + if (x + y < size2 - 1) { + u = (SplashCoord)x + 0.5 - 0; v = (SplashCoord)y + 0.5 - 0; } else { - u = (SplashCoord)x + 0.5 - (SplashCoord)size; //~ ((SplashCoord)size - 0.5); - v = (SplashCoord)y + 0.5 - (SplashCoord)size; + u = (SplashCoord)x + 0.5 - (SplashCoord)size2; + v = (SplashCoord)y + 0.5 - (SplashCoord)size2; } - dist[y * size + x] = u*u + v*v; + dist[y * size2 + x] = u*u + v*v; } } - for (y = 0; y < size; ++y) { - for (x = 0; x < size; ++x) { + for (y = 0; y < size2; ++y) { + for (x = 0; x < size2; ++x) { if (x < y) { - u = (SplashCoord)x + 0.5 - 0; //~ (-0.5); - v = (SplashCoord)y + 0.5 - (SplashCoord)size; + u = (SplashCoord)x + 0.5 - 0; + v = (SplashCoord)y + 0.5 - (SplashCoord)size2; } else { - u = (SplashCoord)x + 0.5 - (SplashCoord)size; //~ ((SplashCoord)size - 0.5); + u = (SplashCoord)x + 0.5 - (SplashCoord)size2; v = (SplashCoord)y + 0.5 - 0; } - dist[(size + y) * size + x] = u*u + v*v; + dist[(size2 + y) * size2 + x] = u*u + v*v; } } // build the threshold matrix + minVal = 1; + maxVal = 0; x1 = y1 = 0; // make gcc happy - for (i = 1; i <= 2 * size * size; ++i) { - d = 2 * size * size; - for (y = 0; y < 2 * size; ++y) { - for (x = 0; x < size; ++x) { + for (i = 1; i <= size * size2; ++i) { + d = size * size2; + for (y = 0; y < size; ++y) { + for (x = 0; x < size2; ++x) { if (mat[y * size + x] < 0 && - dist[y * size + x] < d) { + dist[y * size2 + x] < d) { x1 = x; y1 = y; - d = dist[y1 * size + x1]; + d = dist[y1 * size2 + x1]; } } } - u = 1.0 - (SplashCoord)i / (SplashCoord)(2 * size * size + 1); - mat[y1 * size + x1] = splashPow(u, 1.33); + u = (SplashCoord)1 - (SplashCoord)i / (SplashCoord)(size * size2 + 1); + val = splashPow(u, 1.33); + if (val < minVal) { + minVal = val; + } + if (val > maxVal) { + maxVal = val; + } + mat[y1 * size + x1] = val; + if (y1 < size2) { + mat[(y1 + size2) * size + x1 + size2] = val; + } else { + mat[(y1 - size2) * size + x1 + size2] = val; + } } gfree(dist); } +SplashScreen::SplashScreen(SplashScreen *screen) { + int n; + + size = screen->size; + n = size * size * sizeof(SplashCoord); + mat = (SplashCoord *)gmalloc(n); + memcpy(mat, screen->mat, n); + minVal = screen->minVal; + maxVal = screen->maxVal; +} + SplashScreen::~SplashScreen() { gfree(mat); } int SplashScreen::test(int x, int y, SplashCoord value) { - SplashCoord *mat1; int xx, yy; - xx = x % (2 * size); - yy = y % (2 * size); - mat1 = mat; - if ((xx / size) ^ (yy / size)) { - mat1 += size * size; + if (value < minVal) { + return 0; + } + if (value >= maxVal) { + return 1; } - xx %= size; - yy %= size; - return value < mat1[yy * size + xx] ? 0 : 1; + if ((xx = x % size) < 0) { + xx = -xx; + } + if ((yy = y % size) < 0) { + yy = -yy; + } + return value < mat[yy * size + xx] ? 0 : 1; +} + +GBool SplashScreen::isStatic(SplashCoord value) { + return value < minVal || value >= maxVal; } diff --git a/splash/SplashScreen.h b/splash/SplashScreen.h index c8b9a8d783e662d69cd9d73b3f1da036ec22b336..e0df8bbd77544b61c744dc7a22f5508cd37e0885 100644 --- a/splash/SplashScreen.h +++ b/splash/SplashScreen.h @@ -21,18 +21,28 @@ class SplashScreen { public: SplashScreen(int sizeA); + SplashScreen(SplashScreen *screen); ~SplashScreen(); - SplashScreen *copy() { return new SplashScreen(size << 1); } + SplashScreen *copy() { return new SplashScreen(this); } // Return the computed pixel value (0=black, 1=white) for the gray // level at (, ). int test(int x, int y, SplashCoord value); + // Returns true if value is above the white threshold or below the + // black threshold, i.e., if the corresponding halftone will be + // solid white or black. + GBool isStatic(SplashCoord value); + private: SplashCoord *mat; // threshold matrix int size; // size of the threshold matrix + SplashCoord minVal; // any pixel value below minVal generates + // solid black + SplashCoord maxVal; // any pixel value above maxVal generates + // solid white }; #endif