📄 splash.cc
字号:
if (debugMode) { printf("fillChar: x=%.2f y=%.2f c=%3d=0x%02x='%c'\n", (double)x, (double)y, c, c, c); } x0 = splashFloor(x); xFrac = splashFloor((x - x0) * splashFontFraction); y0 = splashFloor(y); yFrac = splashFloor((y - y0) * splashFontFraction); if (!font->getGlyph(c, xFrac, yFrac, &glyph)) { return splashErrNoGlyph; } err = fillGlyph(x, y, &glyph); if (glyph.freeData) { gfree(glyph.data); } return err;}SplashError Splash::fillGlyph(SplashCoord x, SplashCoord y, SplashGlyphBitmap *glyph) { SplashBlendFunc blendFunc; int alpha0, alpha, ialpha; Guchar *p; SplashColor fg, dest, blend; SplashColorPtr pix; SplashClipResult clipRes; GBool noClip; Guchar t; int x0, y0, x1, y1, xx, xx1, yy; x0 = splashFloor(x); y0 = splashFloor(y); if ((clipRes = state->clip->testRect(x0 - glyph->x, y0 - glyph->y, x0 - glyph->x + glyph->w - 1, y0 - glyph->y + glyph->h - 1)) != splashClipAllOutside) { noClip = clipRes == splashClipAllInside; if (noClip) { updateModX(x0 - glyph->x); updateModX(x0 - glyph->x + glyph->w - 1); updateModY(y0 - glyph->y); updateModY(y0 - glyph->y + glyph->h - 1); } //~ optimize this if (state->fillAlpha != 1 || softMask || state->blendFunc) { blendFunc = state->blendFunc ? state->blendFunc : &blendNormal; if (glyph->aa) { p = glyph->data; for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) { alpha = *p++; if (softMask) { alpha = (int)(alpha * state->fillAlpha * softMask->data[y1 * softMask->rowSize + x1]); } else { alpha = (int)(alpha * state->fillAlpha); } if (alpha > 0) { if (noClip || state->clip->test(x1, y1)) { ialpha = 255 - alpha; state->fillPattern->getColor(x1, y1, fg); switch (bitmap->mode) { case splashModeMono1: pix = &bitmap->data[y1 * bitmap->rowSize + (x1 >> 3)]; dest[0] = (*pix >> (7 - (x1 & 7))) & 1; (*blendFunc)(fg, dest, blend, bitmap->mode); t = (alpha * blend[0] + ialpha * dest[0]) >> 8; if (t) { *pix |= 0x80 >> (x1 & 7); } else { *pix &= ~(0x80 >> (x1 & 7)); } break; case splashModeMono8: pix = &bitmap->data[y1 * bitmap->rowSize + x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); // note: floor(x / 255) = x >> 8 (for 16-bit x) pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; break; case splashModeAMono8: pix = &bitmap->data[y1 * bitmap->rowSize + 2 * x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; break; case splashModeRGB8: case splashModeBGR8: pix = &bitmap->data[y1 * bitmap->rowSize + 3 * x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; break; case splashModeARGB8: case splashModeBGRA8:#if SPLASH_CMYK case splashModeCMYK8:#endif pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; pix[3] = (alpha * blend[3] + ialpha * pix[3]) >> 8; break;#if SPLASH_CMYK case splashModeACMYK8: pix = &bitmap->data[y1 * bitmap->rowSize + 5 * x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; pix[3] = (alpha * blend[3] + ialpha * pix[3]) >> 8; pix[4] = (alpha * blend[4] + ialpha * pix[4]) >> 8; break;#endif } if (!noClip) { updateModX(x1); updateModY(y1); } } } } } } else { p = glyph->data; for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++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) { if (alpha0 & 0x80) { if (noClip || state->clip->test(x1, y1)) { if (softMask) { alpha = (int)(state->fillAlpha * softMask->data[y1 * softMask->rowSize + x1]); } else { alpha = (int)(state->fillAlpha * 255); } ialpha = 255 - alpha; state->fillPattern->getColor(x1, y1, fg); switch (bitmap->mode) { case splashModeMono1: pix = &bitmap->data[y1 * bitmap->rowSize + (x1 >> 3)]; dest[0] = (*pix >> (7 - (x1 & 7))) & 1; (*blendFunc)(fg, dest, blend, bitmap->mode); t = (alpha * blend[0] + ialpha * dest[0]) >> 8; if (t) { *pix |= 0x80 >> (x1 & 7); } else { *pix &= ~(0x80 >> (x1 & 7)); } break; case splashModeMono8: pix = &bitmap->data[y1 * bitmap->rowSize + x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); // note: floor(x / 255) = x >> 8 (for 16-bit x) pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; break; case splashModeAMono8: pix = &bitmap->data[y1 * bitmap->rowSize + 2 * x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; break; case splashModeRGB8: case splashModeBGR8: pix = &bitmap->data[y1 * bitmap->rowSize + 3 * x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; break; case splashModeARGB8: case splashModeBGRA8:#if SPLASH_CMYK case splashModeCMYK8:#endif pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; pix[3] = (alpha * blend[3] + ialpha * pix[3]) >> 8; break;#if SPLASH_CMYK case splashModeACMYK8: pix = &bitmap->data[y1 * bitmap->rowSize + 5 * x1]; (*blendFunc)(fg, pix, blend, bitmap->mode); pix[0] = (alpha * blend[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * blend[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * blend[2] + ialpha * pix[2]) >> 8; pix[3] = (alpha * blend[3] + ialpha * pix[3]) >> 8; pix[4] = (alpha * blend[4] + ialpha * pix[4]) >> 8; break;#endif } if (!noClip) { updateModX(x1); updateModY(y1); } } } alpha0 <<= 1; } } } } } else { if (glyph->aa) { p = glyph->data; for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) { for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) { alpha = *p++; if (alpha > 0) { if (noClip || state->clip->test(x1, y1)) { ialpha = 255 - alpha; state->fillPattern->getColor(x1, y1, fg); switch (bitmap->mode) { case splashModeMono1: if (alpha >= 0x80) { pix = &bitmap->data[y1 * bitmap->rowSize + (x1 >> 3)]; if (fg[0]) { *pix |= 0x80 >> (x1 & 7); } else { *pix &= ~(0x80 >> (x1 & 7)); } } break; case splashModeMono8: pix = &bitmap->data[y1 * bitmap->rowSize + x1]; // note: floor(x / 255) = x >> 8 (for 16-bit x) pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; break; case splashModeAMono8: pix = &bitmap->data[y1 * bitmap->rowSize + 2 * x1]; pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; break; case splashModeRGB8: case splashModeBGR8: pix = &bitmap->data[y1 * bitmap->rowSize + 3 * x1]; pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * fg[2] + ialpha * pix[2]) >> 8; break; case splashModeARGB8: case splashModeBGRA8:#if SPLASH_CMYK case splashModeCMYK8:#endif pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * fg[2] + ialpha * pix[2]) >> 8; pix[3] = (alpha * fg[3] + ialpha * pix[3]) >> 8; break;#if SPLASH_CMYK case splashModeACMYK8: pix = &bitmap->data[y1 * bitmap->rowSize + 5 * x1]; pix[0] = (alpha * fg[0] + ialpha * pix[0]) >> 8; pix[1] = (alpha * fg[1] + ialpha * pix[1]) >> 8; pix[2] = (alpha * fg[2] + ialpha * pix[2]) >> 8; pix[3] = (alpha * fg[3] + ialpha * pix[3]) >> 8; pix[4] = (alpha * fg[4] + ialpha * pix[4]) >> 8; break;#endif } if (!noClip) { updateModX(x1); updateModY(y1); } } } } } } else { p = glyph->data; for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++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) { if (alpha0 & 0x80) { if (noClip || state->clip->test(x1, y1)) { state->fillPattern->getColor(x1, y1, fg); switch (bitmap->mode) { case splashModeMono1: pix = &bitmap->data[y1 * bitmap->rowSize + (x1 >> 3)]; if (fg[0]) { *pix |= 0x80 >> (x1 & 7); } else { *pix &= ~(0x80 >> (x1 & 7)); } break; case splashModeMono8: pix = &bitmap->data[y1 * bitmap->rowSize + x1]; pix[0] = fg[0]; break; case splashModeAMono8: pix = &bitmap->data[y1 * bitmap->rowSize + 2 * x1]; pix[0] = fg[0]; pix[1] = fg[1]; break; case splashModeRGB8: case splashModeBGR8: pix = &bitmap->data[y1 * bitmap->rowSize + 3 * x1]; pix[0] = fg[0]; pix[1] = fg[1]; pix[2] = fg[2]; break; case splashModeARGB8: case splashModeBGRA8:#if SPLASH_CMYK case splashModeCMYK8:#endif pix = &bitmap->data[y1 * bitmap->rowSize + 4 * x1]; pix[0] = fg[0]; pix[1] = fg[1]; pix[2] = fg[2]; pix[3] = fg[3]; break;#if SPLASH_CMYK case splashModeACMYK8: pix = &bitmap->data[y1 * bitmap->rowSize + 5 * x1]; pix[0] = fg[0]; pix[1] = fg[1]; pix[2] = fg[2]; pix[3] = fg[3]; pix[4] = fg[4]; break;#endif } if (!noClip) { updateModX(x1); updateModY(y1); } } } alpha0 <<= 1; } } } } } } opClipRes = clipRes; return splashOk;}SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData, int w, int h, SplashCoord *mat) { GBool rot; SplashCoord xScale, yScale, xShear, yShear, yShear1; int tx, tx2, ty, ty2, scaledWidth, scaledHeight, xSign, ySign; int ulx, uly, llx, lly, urx, ury, lrx, lry; int ulx1, uly1, llx1, lly1, urx1, ury1, lrx1, lry1; int xMin, xMax, yMin, yMax; SplashClipResult clipRes, clipRes2; int yp, yq, yt, yStep, lastYStep; int xp, xq, xt, xStep, xSrc; int k1, spanXMin, spanXMax, spanY; SplashColorPtr pixBuf, p; int pixAcc; SplashCoord alpha; int x, y, x1, x2, y2; SplashCoord y1; int n, m, i, j; if (debugMode) { printf("fillImageMask: w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n", w, h, (double)mat[0], (double)mat[1], (double)mat[2], (double)mat[3], (double)mat[4], (double)mat[5]); } // check for singular matrix if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.000001) { return splashErrSingularMatrix; } // compute scale, shear, rotation, translation parameters rot = splashAbs(mat[1]) > splashAbs(mat[0]); if (rot) { xScale = -mat[1]; yScale = mat[2] - (mat[0] * mat[3]) / mat[1]; xShear = -mat[3] / yScale; yShear = -mat[0] / mat[1]; } else { xScale = mat[0]; yScale = mat[3] - (mat[1] * mat[2]) / mat[0]; xShear = mat[2] / yScale; yShear = mat[1] / mat[0]; } // the +/-0.01 in these computations is to avoid floating point // precision problems which can lead to gaps between image stripes // (it can cause image stripes to overlap, but that's a much less // visible problem) if (xScale >= 0) { tx = splashRound(mat[4] - 0.01); tx2 = splashRound(mat[4] + xScale + 0.01) - 1; } else { tx = splashRound(mat[4] + 0.01) - 1; tx2 = splashRound(mat[4] + xScale - 0.01); } scaledWidth = abs(tx2 - tx) + 1; if (scaledWidth == 0) { // technically, this should draw nothing, but it generally seems // better to draw a one-pixel-wide stripe rather than throwing it // away scaledWidth = 1; } if (yScale >= 0) { ty = splashRound(mat[5] - 0.01); ty2 = splashRound(mat[5] + yScale + 0.01) - 1; } else { ty = splashRound(mat[5] + 0.01) - 1; ty2 = splashRound(mat[5] + yScale - 0.01); } scaledHeight = abs(ty2 - ty) + 1; if (scaledHeight == 0) { // technically, this should draw nothing, but it generally seems // better to draw a one-pixel-wide stripe rather than throwing it // away scaledHeight = 1; } xSign = (xScale < 0) ? -1 : 1; ySign = (yScale < 0) ? -1 : 1; yShear1 = (SplashCoord)xSign * yShear; // clipping ulx1 = 0; uly1 = 0; urx1 = xSign * (scaledWidth - 1); ury1 = (int)(yShear * urx1); llx1 = splashRound(xShear * ySign * (scaledHeight - 1)); lly1 = ySign * (scaledHeight - 1) + (int)(yShear * llx1); lrx1 = xSign * (scaledWidth - 1) + splashRound(xShear * ySign * (scaledHeight - 1)); lry1 = ySign * (scaledHeight - 1) + (int)(yShear * lrx1); if (rot) { ulx = tx + uly1; uly = ty - ulx1; urx = tx + ury1; ury = ty - urx1; llx = tx + lly1; lly = ty - llx1; lrx = tx + lry1; lry = ty - lrx1; } else { ulx = tx + ulx1; uly = ty + uly1; urx = tx + urx1; ury = ty + ury1; llx = tx + llx1; lly = ty + lly1; lrx = tx + lrx1; lry = ty + lry1; } xMin = (ulx < urx) ? (ulx < llx) ? (ulx < lrx) ? ulx : lrx : (llx < lrx) ? llx : lrx : (urx < llx) ? (urx < lrx) ? urx : lrx : (llx < lrx) ? llx : lrx; xMax = (ulx > urx) ? (ulx > llx) ? (ulx > lrx) ? ulx : lrx : (llx > lrx) ? llx : lrx : (urx > llx) ? (urx > lrx) ? urx : lrx : (llx > lrx) ? llx : lrx; yMin = (uly < ury) ? (uly < lly) ? (uly < lry) ? uly : lry : (lly < lry) ? lly : lry : (ury < lly) ? (ury < lry) ? ury : lry : (lly < lry) ? lly : lry; yMax = (uly > ury) ? (uly > lly) ? (uly > lry) ? uly : lry : (lly > lry) ? lly : lry : (ury > lly) ? (ury > lry) ? ury : lry : (lly > lry) ? lly : lry; clipRes = state->clip->testRect(xMin, yMin, xMax, yMax); opClipRes = clipRes; // compute Bresenham parameters for x and y scaling yp = h / scaledHeight; yq = h % scaledHeight; xp = w / scaledWidth; xq = w % scaledWidth; // allocate pixel buffer pixBuf = (SplashColorPtr)gmalloc((yp + 1) * w); // init y scale Bresenham yt = 0; lastYStep = 1; for (y = 0; y < scaledHeigh
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -