diff --git a/xpdf/splash/Splash.cc b/xpdf/splash/Splash.cc index 3c252e062..f05b891ad 100644 --- a/xpdf/splash/Splash.cc +++ b/xpdf/splash/Splash.cc @@ -1674,15 +1674,37 @@ void Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph, GBool noClip) Guchar *p; int x1, y1, xx, xx1, yy; + p = glyph->data; + int xStart = x0 - glyph->x; + int yStart = y0 - glyph->y; + int xxLimit = glyph->w; + int yyLimit = glyph->h; + + if (yStart < 0) + { + p += glyph->w * -yStart; // move p to the beginning of the first painted row + yyLimit += yStart; + yStart = 0; + } + + if (xStart < 0) + { + p += -xStart; // move p to the first painted pixel + xxLimit += xStart; + xStart = 0; + } + + if (xxLimit + xStart >= bitmap->width) xxLimit = bitmap->width - xStart; + if (yyLimit + yStart >= bitmap->height) yyLimit = bitmap->height - yStart; + if (noClip) { if (glyph->aa) { - pipeInit(&pipe, x0 - glyph->x, y0 - glyph->y, + pipeInit(&pipe, xStart, yStart, state->fillPattern, NULL, state->fillAlpha, gTrue, gFalse); - p = glyph->data; - for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { - pipeSetXY(&pipe, x0 - glyph->x, y1); - for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) { - alpha = *p++; + for (yy = 0, y1 = yStart; yy < yyLimit; ++yy, ++y1) { + pipeSetXY(&pipe, xStart, y1); + for (xx = 0, x1 = xStart; xx < xxLimit; ++xx, ++x1) { + alpha = p[xx]; if (alpha != 0) { pipe.shape = (SplashCoord)(alpha / 255.0); pipeRun(&pipe); @@ -1692,16 +1714,16 @@ void Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph, GBool noClip) pipeIncX(&pipe); } } + p += glyph->w; } } else { - pipeInit(&pipe, x0 - glyph->x, y0 - glyph->y, + pipeInit(&pipe, xStart, yStart, state->fillPattern, NULL, state->fillAlpha, gFalse, gFalse); - p = glyph->data; - for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { - pipeSetXY(&pipe, x0 - glyph->x, y1); - for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; xx += 8) { - alpha0 = *p++; - for (xx1 = 0; xx1 < 8 && xx + xx1 < glyph->w; ++xx1, ++x1) { + for (yy = 0, y1 = yStart; yy < yyLimit; ++yy, ++y1) { + pipeSetXY(&pipe, xStart, y1); + for (xx = 0, x1 = xStart; xx < xxLimit; xx += 8) { + alpha0 = p[xx]; + for (xx1 = 0; xx1 < 8 && xx + xx1 < xxLimit; ++xx1, ++x1) { if (alpha0 & 0x80) { pipeRun(&pipe); updateModX(x1); @@ -1712,18 +1734,18 @@ void Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph, GBool noClip) alpha0 <<= 1; } } + p += glyph->w; } } } else { if (glyph->aa) { - pipeInit(&pipe, x0 - glyph->x, y0 - glyph->y, + pipeInit(&pipe, xStart, yStart, state->fillPattern, NULL, state->fillAlpha, gTrue, gFalse); - p = glyph->data; - for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { - pipeSetXY(&pipe, x0 - glyph->x, y1); - for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) { + for (yy = 0, y1 = yStart; yy < yyLimit; ++yy, ++y1) { + pipeSetXY(&pipe, xStart, y1); + for (xx = 0, x1 = xStart; xx < xxLimit; ++xx, ++x1) { if (state->clip->test(x1, y1)) { - alpha = *p++; + alpha = p[xx]; if (alpha != 0) { pipe.shape = (SplashCoord)(alpha / 255.0); pipeRun(&pipe); @@ -1734,19 +1756,18 @@ void Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph, GBool noClip) } } else { pipeIncX(&pipe); - ++p; } } + p += glyph->w; } } else { - pipeInit(&pipe, x0 - glyph->x, y0 - glyph->y, + pipeInit(&pipe, xStart, yStart, state->fillPattern, NULL, state->fillAlpha, gFalse, gFalse); - p = glyph->data; - for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { - pipeSetXY(&pipe, x0 - glyph->x, y1); - for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; xx += 8) { - alpha0 = *p++; - for (xx1 = 0; xx1 < 8 && xx + xx1 < glyph->w; ++xx1, ++x1) { + for (yy = 0, y1 = yStart; yy < yyLimit; ++yy, ++y1) { + pipeSetXY(&pipe, xStart, y1); + for (xx = 0, x1 = xStart; xx < xxLimit; xx += 8) { + alpha0 = p[xx]; + for (xx1 = 0; xx1 < 8 && xx + xx1 < xxLimit; ++xx1, ++x1) { if (state->clip->test(x1, y1)) { if (alpha0 & 0x80) { pipeRun(&pipe); @@ -1761,6 +1782,7 @@ void Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph, GBool noClip) alpha0 <<= 1; } } + p += glyph->w; } } }