📄 splash.cc
字号:
//========================================================================//// Splash.cc////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdlib.h>#include <string.h>#include "gmem.h"#include "SplashErrorCodes.h"#include "SplashMath.h"#include "SplashBitmap.h"#include "SplashState.h"#include "SplashPath.h"#include "SplashXPath.h"#include "SplashXPathScanner.h"#include "SplashPattern.h"#include "SplashScreen.h"#include "SplashFont.h"#include "SplashGlyphBitmap.h"#include "Splash.h"//------------------------------------------------------------------------static void blendNormal(SplashColorPtr src, SplashColorPtr dest, SplashColorPtr blend, SplashColorMode cm) { int i; for (i = 0; i < splashColorModeNComps[cm]; ++i) { blend[i] = src[i]; }}//------------------------------------------------------------------------// Splash//------------------------------------------------------------------------Splash::Splash(SplashBitmap *bitmapA) { bitmap = bitmapA; state = new SplashState(bitmap->width, bitmap->height); softMask = NULL; clearModRegion(); debugMode = gFalse;}Splash::~Splash() { while (state->next) { restoreState(); } delete state; if (softMask) { delete softMask; }}//------------------------------------------------------------------------// state read//------------------------------------------------------------------------SplashPattern *Splash::getStrokePattern() { return state->strokePattern;}SplashPattern *Splash::getFillPattern() { return state->fillPattern;}SplashScreen *Splash::getScreen() { return state->screen;}SplashBlendFunc Splash::getBlendFunc() { return state->blendFunc;}SplashCoord Splash::getStrokeAlpha() { return state->strokeAlpha;}SplashCoord Splash::getFillAlpha() { return state->fillAlpha;}SplashCoord Splash::getLineWidth() { return state->lineWidth;}int Splash::getLineCap() { return state->lineCap;}int Splash::getLineJoin() { return state->lineJoin;}SplashCoord Splash::getMiterLimit() { return state->miterLimit;}SplashCoord Splash::getFlatness() { return state->flatness;}SplashCoord *Splash::getLineDash() { return state->lineDash;}int Splash::getLineDashLength() { return state->lineDashLength;}SplashCoord Splash::getLineDashPhase() { return state->lineDashPhase;}SplashClip *Splash::getClip() { return state->clip;}//------------------------------------------------------------------------// state write//------------------------------------------------------------------------void Splash::setStrokePattern(SplashPattern *strokePattern) { state->setStrokePattern(strokePattern);}void Splash::setFillPattern(SplashPattern *fillPattern) { state->setFillPattern(fillPattern);}void Splash::setScreen(SplashScreen *screen) { state->setScreen(screen);}void Splash::setBlendFunc(SplashBlendFunc func) { state->blendFunc = func;}void Splash::setStrokeAlpha(SplashCoord alpha) { state->strokeAlpha = alpha;}void Splash::setFillAlpha(SplashCoord alpha) { state->fillAlpha = alpha;}void Splash::setLineWidth(SplashCoord lineWidth) { state->lineWidth = lineWidth;}void Splash::setLineCap(int lineCap) { state->lineCap = lineCap;}void Splash::setLineJoin(int lineJoin) { state->lineJoin = lineJoin;}void Splash::setMiterLimit(SplashCoord miterLimit) { state->miterLimit = miterLimit;}void Splash::setFlatness(SplashCoord flatness) { if (flatness < 1) { state->flatness = 1; } else { state->flatness = flatness; }}void Splash::setLineDash(SplashCoord *lineDash, int lineDashLength, SplashCoord lineDashPhase) { state->setLineDash(lineDash, lineDashLength, lineDashPhase);}void Splash::clipResetToRect(SplashCoord x0, SplashCoord y0, SplashCoord x1, SplashCoord y1) { state->clip->resetToRect(x0, y0, x1, y1);}SplashError Splash::clipToRect(SplashCoord x0, SplashCoord y0, SplashCoord x1, SplashCoord y1) { return state->clip->clipToRect(x0, y0, x1, y1);}SplashError Splash::clipToPath(SplashPath *path, GBool eo) { return state->clip->clipToPath(path, state->flatness, eo);}//------------------------------------------------------------------------// state save/restore//------------------------------------------------------------------------void Splash::saveState() { SplashState *newState; newState = state->copy(); newState->next = state; state = newState;}SplashError Splash::restoreState() { SplashState *oldState; if (!state->next) { return splashErrNoSave; } oldState = state; state = state->next; delete oldState; return splashOk;}//------------------------------------------------------------------------// soft mask//------------------------------------------------------------------------void Splash::setSoftMask(SplashBitmap *softMaskA) { if (softMask) { delete softMask; } softMask = softMaskA;}//------------------------------------------------------------------------// modified region//------------------------------------------------------------------------void Splash::clearModRegion() { modXMin = bitmap->getWidth(); modYMin = bitmap->getHeight(); modXMax = -1; modYMax = -1;}inline void Splash::updateModX(int x) { if (x < modXMin) { modXMin = x; } if (x > modXMax) { modXMax = x; }}inline void Splash::updateModY(int y) { if (y < modYMin) { modYMin = y; } if (y > modYMax) { modYMax = y; }}//------------------------------------------------------------------------// drawing operations//------------------------------------------------------------------------void Splash::clear(SplashColorPtr color) { SplashColorPtr row, p; Guchar mono; int x, y; switch (bitmap->mode) { case splashModeMono1: mono = color[0] ? 0xff : 0x00; if (bitmap->rowSize < 0) { memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), mono, -bitmap->rowSize * bitmap->height); } else { memset(bitmap->data, mono, bitmap->rowSize * bitmap->height); } break; case splashModeMono8: if (bitmap->rowSize < 0) { memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), color[0], -bitmap->rowSize * bitmap->height); } else { memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); } break; case splashModeAMono8: if (color[0] == color[1]) { if (bitmap->rowSize < 0) { memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), color[0], -bitmap->rowSize * bitmap->height); } else { memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); } } else { row = bitmap->data; for (y = 0; y < bitmap->height; ++y) { p = row; for (x = 0; x < bitmap->width; ++x) { *p++ = color[0]; *p++ = color[1]; } row += bitmap->rowSize; } } break; case splashModeRGB8: case splashModeBGR8: if (color[0] == color[1] && color[1] == color[2]) { if (bitmap->rowSize < 0) { memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), color[0], -bitmap->rowSize * bitmap->height); } else { memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); } } else { row = bitmap->data; for (y = 0; y < bitmap->height; ++y) { p = row; for (x = 0; x < bitmap->width; ++x) { *p++ = color[0]; *p++ = color[1]; *p++ = color[2]; } row += bitmap->rowSize; } } break; case splashModeARGB8: case splashModeBGRA8:#if SPLASH_CMYK case splashModeCMYK8:#endif if (color[0] == color[1] && color[1] == color[2] && color[2] == color[3]) { if (bitmap->rowSize < 0) { memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), color[0], -bitmap->rowSize * bitmap->height); } else { memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); } } else { row = bitmap->data; for (y = 0; y < bitmap->height; ++y) { p = row; for (x = 0; x < bitmap->width; ++x) { *p++ = color[0]; *p++ = color[1]; *p++ = color[2]; *p++ = color[3]; } row += bitmap->rowSize; } } break;#if SPLASH_CMYK case splashModeACMYK8: if (color[0] == color[1] && color[1] == color[2] && color[2] == color[3] && color[3] == color[4]) { if (bitmap->rowSize < 0) { memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), color[0], -bitmap->rowSize * bitmap->height); } else { memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); } } else { row = bitmap->data; for (y = 0; y < bitmap->height; ++y) { p = row; for (x = 0; x < bitmap->width; ++x) { *p++ = color[0]; *p++ = color[1]; *p++ = color[2]; *p++ = color[3]; *p++ = color[4]; } row += bitmap->rowSize; } } break;#endif } updateModX(0); updateModY(0); updateModX(bitmap->width - 1); updateModY(bitmap->height - 1);}SplashError Splash::stroke(SplashPath *path) { SplashXPath *xPath, *xPath2; if (debugMode) { printf("stroke [dash:%d] [width:%.2f]:\n", state->lineDashLength, (double)state->lineWidth); dumpPath(path); } opClipRes = splashClipAllOutside; if (path->length == 0) { return splashErrEmptyPath; } xPath = new SplashXPath(path, state->flatness, gFalse); if (xPath->length == 0) { delete xPath; return splashErrEmptyPath; } if (state->lineDashLength > 0) { xPath2 = makeDashedPath(xPath); delete xPath; xPath = xPath2; } if (state->lineWidth <= 1) { strokeNarrow(xPath); } else { strokeWide(xPath); } delete xPath; return splashOk;}void Splash::strokeNarrow(SplashXPath *xPath) { SplashXPathSeg *seg; int x0, x1, x2, x3, y0, y1, x, y, t; SplashCoord dx, dy, dxdy; SplashClipResult clipRes; int nClipRes[3]; int i; for (i = 0, seg = xPath->segs; i < xPath->length; ++i, ++seg) { x0 = splashFloor(seg->x0); x1 = splashFloor(seg->x1); y0 = splashFloor(seg->y0); y1 = splashFloor(seg->y1); // horizontal segment if (y0 == y1) { if (x0 > x1) { t = x0; x0 = x1; x1 = t; } if ((clipRes = state->clip->testSpan(x0, x1, y0)) != splashClipAllOutside) { drawSpan(x0, x1, y0, state->strokePattern, state->strokeAlpha, clipRes == splashClipAllInside); } // segment with |dx| > |dy| } else if (splashAbs(seg->dxdy) > 1) { dx = seg->x1 - seg->x0; dy = seg->y1 - seg->y0; dxdy = seg->dxdy; if (y0 > y1) { t = y0; y0 = y1; y1 = t; t = x0; x0 = x1; x1 = t; dx = -dx; dy = -dy; } if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0, x0 <= x1 ? x1 : x0, y1)) != splashClipAllOutside) { if (dx > 0) { x2 = x0; x3 = splashFloor(seg->x0 + ((SplashCoord)y0 + 1 - seg->y0) * dxdy); drawSpan(x2, (x2 <= x3 - 1) ? x3 - 1 : x2, y0, state->strokePattern, state->strokeAlpha, clipRes == splashClipAllInside); x2 = x3; for (y = y0 + 1; y <= y1 - 1; ++y) { x3 = splashFloor(seg->x0 + ((SplashCoord)y + 1 - seg->y0) * dxdy); drawSpan(x2, x3 - 1, y, state->strokePattern, state->strokeAlpha, clipRes == splashClipAllInside); x2 = x3; } drawSpan(x2, x2 <= x1 ? x1 : x2, y1, state->strokePattern, state->strokeAlpha, clipRes == splashClipAllInside); } else { x2 = x0; x3 = splashFloor(seg->x0 + ((SplashCoord)y0 + 1 - seg->y0) * dxdy); drawSpan((x3 + 1 <= x2) ? x3 + 1 : x2, x2, y0, state->strokePattern, state->strokeAlpha, clipRes == splashClipAllInside); x2 = x3; for (y = y0 + 1; y <= y1 - 1; ++y) { x3 = splashFloor(seg->x0 + ((SplashCoord)y + 1 - seg->y0) * dxdy); drawSpan(x3 + 1, x2, y, state->strokePattern, state->strokeAlpha, clipRes == splashClipAllInside); x2 = x3; } drawSpan(x1, (x1 <= x2) ? x2 : x1, y1, state->strokePattern, state->strokeAlpha, clipRes == splashClipAllInside); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -