Fix save Redact

This commit is contained in:
Svetlana Kulikova
2025-10-01 14:30:46 +03:00
parent 964a3b455b
commit ad496ca7cd
7 changed files with 192 additions and 508 deletions

View File

@ -3579,7 +3579,9 @@ void CPdfEditor::Redact(IAdvancedCommand* _pCommand)
pPage->getContents(&oContents); pPage->getContents(&oContents);
PDFRectangle* box = pPage->getMediaBox(); PDFRectangle* box = pPage->getMediaBox();
Gfx* gfx = new Gfx(pPDFDocument, &oRedactOut, nPageIndex, pPage->getResourceDict(), 72.0, 72.0, box, NULL, 0); Gfx* gfx = new Gfx(pPDFDocument, &oRedactOut, nPageIndex, pPage->getResourceDict(), 72.0, 72.0, box, NULL, 0);
gfx->saveState();
gfx->display(&oContents); gfx->display(&oContents);
gfx->endOfPage();
oContents.free(); oContents.free();
RELEASEOBJECT(gfx); RELEASEOBJECT(gfx);
#endif #endif

View File

@ -56,7 +56,7 @@ RedactOutputDev::RedactOutputDev(CPdfWriter* pRenderer)
m_pDoc = m_pRenderer->GetDocument(); m_pDoc = m_pRenderer->GetDocument();
m_pPage = NULL; m_pPage = NULL;
m_nRI = 1; m_bUpdateAll = false;
} }
RedactOutputDev::~RedactOutputDev() RedactOutputDev::~RedactOutputDev()
{ {
@ -103,43 +103,43 @@ void RedactOutputDev::endPage()
//----- save/restore graphics state //----- save/restore graphics state
void RedactOutputDev::saveState(GfxState *pGState) void RedactOutputDev::saveState(GfxState *pGState)
{ {
m_pRenderer->m_oCommandManager.Flush();
DoStateOp();
m_pPage->GrSave();
m_sStates.push_back(GfxRedactState()); m_sStates.push_back(GfxRedactState());
updateAll(pGState); updateAll(pGState);
} }
void RedactOutputDev::restoreState(GfxState *pGState) void RedactOutputDev::restoreState(GfxState *pGState)
{ {
m_pRenderer->m_oCommandManager.Flush();
m_pPage->GrRestore();
updateAll(pGState); updateAll(pGState);
if (m_sStates.empty()) if (m_sStates.empty())
{
UpdateAllClip(pGState);
return; // Несбалансированный q/Q - сломанный файл return; // Несбалансированный q/Q - сломанный файл
}
bool bClipChanged = m_sStates.back().m_pClip;
m_sStates.pop_back(); m_sStates.pop_back();
if (bClipChanged)
UpdateAllClip(pGState);
} }
//----- update graphics state //----- update graphics state
void RedactOutputDev::updateAll(GfxState *pGState) void RedactOutputDev::updateAll(GfxState *pGState)
{ {
m_bUpdateAll = true;
updateLineDash(pGState); updateLineDash(pGState);
updateFlatness(pGState); updateFlatness(pGState);
updateLineJoin(pGState); updateLineJoin(pGState);
updateLineCap(pGState); updateLineCap(pGState);
updateMiterLimit(pGState); updateMiterLimit(pGState);
updateLineWidth(pGState); updateLineWidth(pGState);
updateStrokeAdjust(pGState); // updateStrokeAdjust(pGState);
updateFillColorSpace(pGState); // updateFillColorSpace(pGState);
updateFillColor(pGState); // updateFillColor(pGState);
updateStrokeColorSpace(pGState); // updateStrokeColorSpace(pGState);
updateStrokeColor(pGState); // updateStrokeColor(pGState);
updateRenderingIntent(pGState); updateRenderingIntent(pGState);
// updateBlendMode(pGState); // updateBlendMode(pGState);
// updateFillOpacity(pGState); // updateFillOpacity(pGState);
// updateStrokeOpacity(pGState); // updateStrokeOpacity(pGState);
updateFont(pGState); updateFont(pGState);
m_bUpdateAll = false;
} }
void RedactOutputDev::updateCTM(GfxState *pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32) void RedactOutputDev::updateCTM(GfxState *pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32)
{ {
@ -164,26 +164,44 @@ void RedactOutputDev::updateLineDash(GfxState *pGState)
m_pRenderer->m_oPen.SetDashOffset(dStart); m_pRenderer->m_oPen.SetDashOffset(dStart);
m_pRenderer->m_oPen.SetDashStyle(Aggplus::DashStyleCustom); m_pRenderer->m_oPen.SetDashStyle(Aggplus::DashStyleCustom);
} }
if (m_bUpdateAll || m_sStates.empty())
return;
std::string sOp = "[ ";
for (int i = 0; i < nSize; ++i)
sOp += (std::to_string(pDash[i]) + " ");
sOp += "] " + std::to_string(dStart);
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "d"));
} }
void RedactOutputDev::updateFlatness(GfxState *pGState) void RedactOutputDev::updateFlatness(GfxState *pGState)
{ {
m_pRenderer->m_oPen.SetFlatness(pGState->getFlatness()); m_pRenderer->m_oPen.SetFlatness(pGState->getFlatness());
if (!m_bUpdateAll && !m_sStates.empty())
m_sStates.back().m_arrOp.push_back(std::make_pair(std::to_string(pGState->getFlatness()), "i"));
} }
void RedactOutputDev::updateLineJoin(GfxState *pGState) void RedactOutputDev::updateLineJoin(GfxState *pGState)
{ {
m_pRenderer->m_oPen.SetJoinStyle(pGState->getLineJoin()); m_pRenderer->m_oPen.SetJoinStyle(pGState->getLineJoin());
if (!m_bUpdateAll && !m_sStates.empty())
m_sStates.back().m_arrOp.push_back(std::make_pair(std::to_string(pGState->getLineJoin()), "j"));
} }
void RedactOutputDev::updateLineCap(GfxState *pGState) void RedactOutputDev::updateLineCap(GfxState *pGState)
{ {
m_pRenderer->m_oPen.SetStartCapStyle(pGState->getLineCap()); m_pRenderer->m_oPen.SetStartCapStyle(pGState->getLineCap());
if (!m_bUpdateAll && !m_sStates.empty())
m_sStates.back().m_arrOp.push_back(std::make_pair(std::to_string(pGState->getLineCap()), "J"));
} }
void RedactOutputDev::updateMiterLimit(GfxState *pGState) void RedactOutputDev::updateMiterLimit(GfxState *pGState)
{ {
m_pRenderer->m_oPen.SetMiter(pGState->getMiterLimit()); m_pRenderer->m_oPen.SetMiter(pGState->getMiterLimit());
if (!m_bUpdateAll && !m_sStates.empty())
m_sStates.back().m_arrOp.push_back(std::make_pair(std::to_string(pGState->getMiterLimit()), "M"));
} }
void RedactOutputDev::updateLineWidth(GfxState *pGState) void RedactOutputDev::updateLineWidth(GfxState *pGState)
{ {
m_pRenderer->m_oPen.SetSize(pGState->getLineWidth()); m_pRenderer->m_oPen.SetSize(pGState->getLineWidth());
if (!m_bUpdateAll && !m_sStates.empty())
m_sStates.back().m_arrOp.push_back(std::make_pair(std::to_string(pGState->getLineWidth()), "w"));
} }
void RedactOutputDev::updateFillColorSpace(GfxState *pGState) void RedactOutputDev::updateFillColorSpace(GfxState *pGState)
{ {
@ -195,77 +213,96 @@ void RedactOutputDev::updateStrokeColorSpace(GfxState *pGState)
} }
void RedactOutputDev::updateFillColor(GfxState *pGState) void RedactOutputDev::updateFillColor(GfxState *pGState)
{ {
if (m_sStates.empty())
return;
GfxColorSpace* pColorSpace = pGState->getFillColorSpace(); GfxColorSpace* pColorSpace = pGState->getFillColorSpace();
GfxColorSpaceMode eMode = pColorSpace->getMode(); GfxColorSpaceMode eMode = pColorSpace->getMode();
GfxColor* pColor = pGState->getFillColor(); GfxColor* pColor = pGState->getFillColor();
switch (eMode) { std::string sOp;
std::string sOp2;
switch (eMode)
{
case csDeviceGray: case csDeviceGray:
{ {
m_pRenderer->m_oBrush.SetDColor2(1, colToDbl(pColor->c[0])); sOp = std::to_string(colToDbl(pColor->c[0]));
sOp2 = "g";
break; break;
} }
case csDeviceRGB: case csDeviceRGB:
{ {
m_pRenderer->m_oBrush.SetDColor2(3, colToDbl(pColor->c[0]), colToDbl(pColor->c[1]), colToDbl(pColor->c[2])); sOp = std::to_string(colToDbl(pColor->c[0])) + " " + std::to_string(colToDbl(pColor->c[1])) + " " + std::to_string(colToDbl(pColor->c[2]));
sOp2 = "rg";
break; break;
} }
case csDeviceCMYK: case csDeviceCMYK:
{ {
m_pRenderer->m_oBrush.SetDColor2(4, colToDbl(pColor->c[0]), colToDbl(pColor->c[1]), colToDbl(pColor->c[2]), colToDbl(pColor->c[3])); sOp = std::to_string(colToDbl(pColor->c[0])) + " " + std::to_string(colToDbl(pColor->c[1])) + " " + std::to_string(colToDbl(pColor->c[2])) + " " + std::to_string(colToDbl(pColor->c[3]));
sOp2 = "k";
break; break;
} }
default: default:
break; break;
} }
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, sOp2));
} }
void RedactOutputDev::updateStrokeColor(GfxState *pGState) void RedactOutputDev::updateStrokeColor(GfxState *pGState)
{ {
if (m_sStates.empty())
return;
GfxColorSpace* pColorSpace = pGState->getStrokeColorSpace(); GfxColorSpace* pColorSpace = pGState->getStrokeColorSpace();
GfxColorSpaceMode eMode = pColorSpace->getMode(); GfxColorSpaceMode eMode = pColorSpace->getMode();
GfxColor* pColor = pGState->getStrokeColor(); GfxColor* pColor = pGState->getStrokeColor();
switch (eMode) { std::string sOp;
std::string sOp2;
switch (eMode)
{
case csDeviceGray: case csDeviceGray:
{ {
m_pRenderer->m_oPen.SetDColor2(1, colToDbl(pColor->c[0])); sOp = std::to_string(colToDbl(pColor->c[0]));
sOp2 = "G";
break; break;
} }
case csDeviceRGB: case csDeviceRGB:
{ {
m_pRenderer->m_oPen.SetDColor2(3, colToDbl(pColor->c[0]), colToDbl(pColor->c[1]), colToDbl(pColor->c[2])); sOp = std::to_string(colToDbl(pColor->c[0])) + " " + std::to_string(colToDbl(pColor->c[1])) + " " + std::to_string(colToDbl(pColor->c[2]));
sOp2 = "RG";
break; break;
} }
case csDeviceCMYK: case csDeviceCMYK:
{ {
m_pRenderer->m_oPen.SetDColor2(4, colToDbl(pColor->c[0]), colToDbl(pColor->c[1]), colToDbl(pColor->c[2]), colToDbl(pColor->c[3])); sOp = std::to_string(colToDbl(pColor->c[0])) + " " + std::to_string(colToDbl(pColor->c[1])) + " " + std::to_string(colToDbl(pColor->c[2])) + " " + std::to_string(colToDbl(pColor->c[3]));
sOp2 = "K";
break; break;
} }
default: default:
break; break;
} }
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, sOp2));
} }
void RedactOutputDev::updateRenderingIntent(GfxState *pGState) void RedactOutputDev::updateRenderingIntent(GfxState *pGState)
{ {
if (m_bUpdateAll || m_sStates.empty())
return;
std::string sOp = "/";
GfxRenderingIntent eRI = pGState->getRenderingIntent(); GfxRenderingIntent eRI = pGState->getRenderingIntent();
if (eRI != m_nRI) switch (eRI)
{ {
m_nRI = eRI; case GfxRenderingIntent::gfxRenderingIntentAbsoluteColorimetric:
switch (eRI) sOp += "AbsoluteColorimetric";
{ break;
case GfxRenderingIntent::gfxRenderingIntentAbsoluteColorimetric: case GfxRenderingIntent::gfxRenderingIntentRelativeColorimetric:
m_pPage->SetRenderingIntent(ERenderingIntent::RenderingIntent_AbsoluteColorimetric); sOp += "RelativeColorimetric";
break; break;
case GfxRenderingIntent::gfxRenderingIntentRelativeColorimetric: case GfxRenderingIntent::gfxRenderingIntentSaturation:
m_pPage->SetRenderingIntent(ERenderingIntent::RenderingIntent_RelativeColorimetric); sOp += "Saturation";
break; break;
case GfxRenderingIntent::gfxRenderingIntentSaturation: case GfxRenderingIntent::gfxRenderingIntentPerceptual:
m_pPage->SetRenderingIntent(ERenderingIntent::RenderingIntent_Saturation); default:
break; sOp += "Perceptual";
case GfxRenderingIntent::gfxRenderingIntentPerceptual: break;
default:
m_pPage->SetRenderingIntent(ERenderingIntent::RenderingIntent_Perceptual);
break;
}
} }
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "ri"));
} }
//----- update text state //----- update text state
void RedactOutputDev::updateFont(GfxState *pGState) void RedactOutputDev::updateFont(GfxState *pGState)
@ -304,7 +341,7 @@ void RedactOutputDev::updateWordSpace(GfxState *pGState)
} }
void RedactOutputDev::updateHorizScaling(GfxState *pGState) void RedactOutputDev::updateHorizScaling(GfxState *pGState)
{ {
m_pRenderer->m_oFont.SetHorizontalScaling(pGState->getHorizScaling()); m_pRenderer->m_oFont.SetHorizontalScaling(pGState->getHorizScaling() * 100);
} }
void RedactOutputDev::updateTextPos(GfxState *pGState) void RedactOutputDev::updateTextPos(GfxState *pGState)
{ {
@ -377,34 +414,8 @@ void RedactOutputDev::clipToStrokePath(GfxState *pGState)
//----- text drawing //----- text drawing
void RedactOutputDev::beginStringOp(GfxState *pGState) void RedactOutputDev::beginStringOp(GfxState *pGState)
{ {
int nDColor2Size; m_pRenderer->m_oCommandManager.Flush();
double* dColor = m_pRenderer->m_oBrush.GetDColor2(nDColor2Size); DoStateOp();
if (nDColor2Size == 1)
m_pPage->SetFillG(dColor[0]);
else if (nDColor2Size == 3)
m_pPage->SetFillRGB(dColor[0], dColor[1], dColor[2]);
else if (nDColor2Size == 4)
m_pPage->SetFillCMYK(dColor[0], dColor[1], dColor[2], dColor[3]);
dColor = m_pRenderer->m_oPen.GetDColor2(nDColor2Size);
if (nDColor2Size == 1)
m_pPage->SetStrokeG(dColor[0]);
else if (nDColor2Size == 3)
m_pPage->SetStrokeRGB(dColor[0], dColor[1], dColor[2]);
else if (nDColor2Size == 4)
m_pPage->SetStrokeCMYK(dColor[0], dColor[1], dColor[2], dColor[3]);
CStream* pStream = m_pPage->GetStream();
for (int i = 0; i < m_sStates.size(); ++i)
{
for (int j = 0; j < m_sStates[i].m_arrOp.size(); ++j)
{
pStream->WriteStr(m_sStates[i].m_arrOp[j].first.c_str());
pStream->WriteChar(' ');
pStream->WriteStr(m_sStates[i].m_arrOp[j].second.c_str());
pStream->WriteStr("\012");
}
}
} }
void RedactOutputDev::endStringOp(GfxState *pGState) void RedactOutputDev::endStringOp(GfxState *pGState)
{ {
@ -508,7 +519,6 @@ void RedactOutputDev::drawChar(GfxState *pGState, double dX, double dY, double d
pText->SetName(m_pRenderer->m_oFont.GetName()); pText->SetName(m_pRenderer->m_oFont.GetName());
pText->SetSize(m_pRenderer->m_oFont.GetSize()); pText->SetSize(m_pRenderer->m_oFont.GetSize());
pText->SetType((EFontType)pGState->getFont()->getType()); pText->SetType((EFontType)pGState->getFont()->getType());
pText->SetAlpha((BYTE)m_pRenderer->m_oBrush.GetAlpha1()); // TODO
pText->SetCharSpace(m_pRenderer->m_oFont.GetCharSpace()); pText->SetCharSpace(m_pRenderer->m_oFont.GetCharSpace());
pText->SetMode(m_pRenderer->m_oFont.GetRenderMode()); pText->SetMode(m_pRenderer->m_oFont.GetRenderMode());
pText->SetRise(m_pRenderer->m_oFont.GetRise()); pText->SetRise(m_pRenderer->m_oFont.GetRise());
@ -569,6 +579,22 @@ void RedactOutputDev::setFillColorSpace(const char* name)
std::string sOp = "/" + std::string(name); std::string sOp = "/" + std::string(name);
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "cs")); m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "cs"));
} }
void RedactOutputDev::setFillColor(Object* args, int numArgs)
{
if (m_sStates.empty())
return;
std::string sOp;
for (int i = 0; i < numArgs; ++i)
{
if (args[i].isName())
sOp += ("/" + std::string(args[i].getName()) + " ");
else if (args[i].isInt())
sOp += (std::to_string(args[i].getInt()) + " ");
else if (args[i].isReal())
sOp += (std::to_string(args[i].getReal()) + " ");
}
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "sc"));
}
void RedactOutputDev::setFillColorN(Object* args, int numArgs) void RedactOutputDev::setFillColorN(Object* args, int numArgs)
{ {
if (m_sStates.empty()) if (m_sStates.empty())
@ -585,9 +611,49 @@ void RedactOutputDev::setFillColorN(Object* args, int numArgs)
} }
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "scn")); m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "scn"));
} }
void RedactOutputDev::setStrokeColorSpace(const char* name)
{
if (m_sStates.empty())
return;
std::string sOp = "/" + std::string(name);
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "CS"));
}
void RedactOutputDev::setStrokeColor(Object* args, int numArgs)
{
if (m_sStates.empty())
return;
std::string sOp;
for (int i = 0; i < numArgs; ++i)
{
if (args[i].isName())
sOp += ("/" + std::string(args[i].getName()) + " ");
else if (args[i].isInt())
sOp += (std::to_string(args[i].getInt()) + " ");
else if (args[i].isReal())
sOp += (std::to_string(args[i].getReal()) + " ");
}
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "SC"));
}
void RedactOutputDev::setStrokeColorN(Object* args, int numArgs)
{
if (m_sStates.empty())
return;
std::string sOp;
for (int i = 0; i < numArgs; ++i)
{
if (args[i].isName())
sOp += ("/" + std::string(args[i].getName()) + " ");
else if (args[i].isInt())
sOp += (std::to_string(args[i].getInt()) + " ");
else if (args[i].isReal())
sOp += (std::to_string(args[i].getReal()) + " ");
}
m_sStates.back().m_arrOp.push_back(std::make_pair(sOp, "SCN"));
}
void RedactOutputDev::setShading(GfxState *pGState, const char* name) void RedactOutputDev::setShading(GfxState *pGState, const char* name)
{ {
m_pRenderer->m_oCommandManager.Flush(); m_pRenderer->m_oCommandManager.Flush();
DoStateOp();
double dShiftX = 0, dShiftY = 0; double dShiftX = 0, dShiftY = 0;
DoTransform(pGState->getCTM(), &dShiftX, &dShiftY, true); DoTransform(pGState->getCTM(), &dShiftX, &dShiftY, true);
@ -596,17 +662,8 @@ void RedactOutputDev::setShading(GfxState *pGState, const char* name)
m_pPage->GrSave(); m_pPage->GrSave();
UpdateTransform(); UpdateTransform();
DoStateOp();
CStream* pStream = m_pPage->GetStream(); CStream* pStream = m_pPage->GetStream();
for (int i = 0; i < m_sStates.size(); ++i)
{
for (int j = 0; j < m_sStates[i].m_arrOp.size(); ++j)
{
pStream->WriteStr(m_sStates[i].m_arrOp[j].first.c_str());
pStream->WriteChar(' ');
pStream->WriteStr(m_sStates[i].m_arrOp[j].second.c_str());
pStream->WriteStr("\012");
}
}
pStream->WriteEscapeName(name); pStream->WriteEscapeName(name);
pStream->WriteChar(' '); pStream->WriteChar(' ');
pStream->WriteStr("sh"); pStream->WriteStr("sh");
@ -649,6 +706,7 @@ void RedactOutputDev::type3D1(GfxState *pGState, double wx, double wy, double ll
void RedactOutputDev::drawForm(GfxState *pGState, Ref id, const char* name) void RedactOutputDev::drawForm(GfxState *pGState, Ref id, const char* name)
{ {
m_pRenderer->m_oCommandManager.Flush(); m_pRenderer->m_oCommandManager.Flush();
DoStateOp();
double dShiftX = 0, dShiftY = 0; double dShiftX = 0, dShiftY = 0;
DoTransform(pGState->getCTM(), &dShiftX, &dShiftY, true); DoTransform(pGState->getCTM(), &dShiftX, &dShiftY, true);
@ -699,23 +757,13 @@ void RedactOutputDev::drawForm(GfxState *pGState, Ref id, const char* name)
m_pPage->GrSave(); m_pPage->GrSave();
UpdateTransform(); UpdateTransform();
CStream* pStream = m_pPage->GetStream();
for (int i = 0; i < m_sStates.size(); ++i)
{
for (int j = 0; j < m_sStates[i].m_arrOp.size(); ++j)
{
pStream->WriteStr(m_sStates[i].m_arrOp[j].first.c_str());
pStream->WriteChar(' ');
pStream->WriteStr(m_sStates[i].m_arrOp[j].second.c_str());
pStream->WriteStr("\012");
}
}
m_pPage->ExecuteXObject(name); m_pPage->ExecuteXObject(name);
m_pPage->GrRestore(); m_pPage->GrRestore();
} }
void RedactOutputDev::drawImage(GfxState *pGState, Ref id, const char* name) void RedactOutputDev::drawImage(GfxState *pGState, Ref id, const char* name)
{ {
m_pRenderer->m_oCommandManager.Flush(); m_pRenderer->m_oCommandManager.Flush();
DoStateOp();
double dShiftX = 0, dShiftY = 0; double dShiftX = 0, dShiftY = 0;
DoTransform(pGState->getCTM(), &dShiftX, &dShiftY, true); DoTransform(pGState->getCTM(), &dShiftX, &dShiftY, true);
@ -739,17 +787,6 @@ void RedactOutputDev::drawImage(GfxState *pGState, Ref id, const char* name)
m_pPage->GrSave(); m_pPage->GrSave();
UpdateTransform(); UpdateTransform();
CStream* pStream = m_pPage->GetStream();
for (int i = 0; i < m_sStates.size(); ++i)
{
for (int j = 0; j < m_sStates[i].m_arrOp.size(); ++j)
{
pStream->WriteStr(m_sStates[i].m_arrOp[j].first.c_str());
pStream->WriteChar(' ');
pStream->WriteStr(m_sStates[i].m_arrOp[j].second.c_str());
pStream->WriteStr("\012");
}
}
m_pPage->ExecuteXObject(name); m_pPage->ExecuteXObject(name);
m_pPage->GrRestore(); m_pPage->GrRestore();
} }
@ -1131,6 +1168,7 @@ void RedactOutputDev::DoTransform(double* pMatrix, double* pdShiftX, double* pdS
void RedactOutputDev::DrawPath(const LONG& lType) void RedactOutputDev::DrawPath(const LONG& lType)
{ {
m_pRenderer->m_oCommandManager.Flush(); m_pRenderer->m_oCommandManager.Flush();
DoStateOp();
bool bStroke = lType & c_nStroke; bool bStroke = lType & c_nStroke;
bool bFill = lType & c_nWindingFillMode; bool bFill = lType & c_nWindingFillMode;
@ -1138,362 +1176,18 @@ void RedactOutputDev::DrawPath(const LONG& lType)
m_pPage->GrSave(); m_pPage->GrSave();
UpdateTransform(); UpdateTransform();
m_pRenderer->m_oPath.Draw(m_pPage, bStroke, bFill, bEoFill);
if (bStroke)
UpdatePen();
bool bCS = false;
CStream* pStream = m_pPage->GetStream();
for (int i = 0; i < m_sStates.size(); ++i)
{
for (int j = 0; j < m_sStates[i].m_arrOp.size(); ++j)
{
pStream->WriteStr(m_sStates[i].m_arrOp[j].first.c_str());
pStream->WriteChar(' ');
std::string sOp = m_sStates[i].m_arrOp[j].second;
pStream->WriteStr(sOp.c_str());
pStream->WriteStr("\012");
if (sOp == "cs" || sOp == "sc" || sOp == "scn")
bCS = true;
}
}
std::wstring sTextureOldPath = L"";
std::wstring sTextureTmpPath = L"";
if ((bFill || bEoFill) && !bCS)
{
if (c_BrushTypeTexture == m_pRenderer->m_oBrush.GetType())
{
sTextureOldPath = m_pRenderer->m_oBrush.GetTexturePath();
//sTextureTmpPath = GetDownloadFile(sTextureOldPath, wsTempDirectory);
if (!sTextureTmpPath.empty())
m_pRenderer->m_oBrush.SetTexturePath(sTextureTmpPath);
}
UpdateBrush(NULL, L"");
}
if (!m_pRenderer->m_pShading)
{
m_pRenderer->m_oPath.Draw(m_pPage, bStroke, bFill, bEoFill);
}
else
{
if (bFill || bEoFill)
{
m_pPage->GrSave();
m_pRenderer->m_oPath.Clip(m_pPage, bEoFill);
if (NULL != m_pRenderer->m_pShadingExtGrState)
m_pPage->SetExtGrState(m_pRenderer->m_pShadingExtGrState);
m_pPage->DrawShading(m_pRenderer->m_pShading);
m_pPage->GrRestore();
}
if (bStroke)
m_pRenderer->m_oPath.Draw(m_pPage, bStroke, false, false);
}
m_pPage->GrRestore(); m_pPage->GrRestore();
if (!sTextureTmpPath.empty())
m_pRenderer->m_oBrush.SetTexturePath(sTextureOldPath);
} }
void RedactOutputDev::UpdateTransform() void RedactOutputDev::UpdateTransform()
{ {
m_pPage->SetTransform(m_arrMatrix[0], m_arrMatrix[1], m_arrMatrix[2], m_arrMatrix[3], m_arrMatrix[4], m_arrMatrix[5]); m_pPage->SetTransform(m_arrMatrix[0], m_arrMatrix[1], m_arrMatrix[2], m_arrMatrix[3], m_arrMatrix[4], m_arrMatrix[5]);
} }
void RedactOutputDev::UpdatePen()
{
int nSize = -1;
double* dColor = m_pRenderer->m_oPen.GetDColor2(nSize);
if (nSize == 1)
m_pPage->SetStrokeG(dColor[0]);
else if (nSize == 3)
m_pPage->SetStrokeRGB(dColor[0], dColor[1], dColor[2]);
else if (nSize == 4)
m_pPage->SetStrokeCMYK(dColor[0], dColor[1], dColor[2], dColor[3]);
// TODO ExtGState
//m_pPage->SetStrokeAlpha((unsigned char)m_pRenderer->m_oPen.GetAlpha());
m_pPage->SetLineWidth(m_pRenderer->m_oPen.GetSize());
LONG lDashStyle = m_pRenderer->m_oPen.GetDashStyle();
if (Aggplus::DashStyleSolid == lDashStyle)
{
// Ничего не делаем
}
else if (Aggplus::DashStyleCustom == lDashStyle)
{
LONG lDashCount = 0;
double* pDashPattern = m_pRenderer->m_oPen.GetDashPattern(lDashCount);
m_pPage->SetDash(pDashPattern, lDashCount, m_pRenderer->m_oPen.GetDashOffset());
}
BYTE nLineCap = m_pRenderer->m_oPen.GetStartCapStyle();
if (nLineCap == 0)
m_pPage->SetLineCap(ELineCapStyle::linecap_Butt);
else if (nLineCap == 1)
m_pPage->SetLineCap(ELineCapStyle::linecap_Round);
else if (nLineCap == 2)
m_pPage->SetLineCap(ELineCapStyle::linecap_ProjectingSquare);
BYTE nLineJoin = m_pRenderer->m_oPen.GetJoinStyle();
if (nLineJoin == 0)
{
m_pPage->SetLineJoin(ELineJoinStyle::linejoin_Miter);
m_pPage->SetMiterLimit(m_pRenderer->m_oPen.GetMiter());
}
else if (nLineJoin == 1)
m_pPage->SetLineJoin(ELineJoinStyle::linejoin_Round);
else if (nLineJoin == 2)
m_pPage->SetLineJoin(ELineJoinStyle::linejoin_Bevel);
double dFlatness = m_pRenderer->m_oPen.GetFlatness();
if (dFlatness > 0.0001)
m_pPage->SetFlat(dFlatness);
}
void RedactOutputDev::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::wstring& wsTempDirectory)
{
m_pRenderer->m_pShading = NULL;
m_pRenderer->m_pShadingExtGrState = NULL;
LONG lBrushType = m_pRenderer->m_oBrush.GetType();
/*
if (c_BrushTypeTexture == lBrushType)
{
std::wstring wsTexturePath = m_oBrush.GetTexturePath();
BYTE nAlpha = m_oBrush.GetTextureAlpha();
CImageFileFormatChecker oImageFormat(wsTexturePath);
PdfWriter::CImageDict* pImage = NULL;
int nImageW = 0;
int nImageH = 0;
bool bHasImage = false;
if (m_pDocument->HasImage(wsTexturePath, nAlpha))
{
pImage = m_pDocument->GetImage(wsTexturePath, nAlpha);
nImageH = pImage->GetHeight();
nImageW = pImage->GetWidth();
bHasImage = true;
}
else if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType || _CXIMAGE_FORMAT_JP2 == oImageFormat.eFileType)
{
pImage = m_pDocument->CreateImage();
CBgraFrame oFrame;
oFrame.OpenFile(wsTexturePath);
nImageH = oFrame.get_Height();
nImageW = oFrame.get_Width();
if (pImage)
{
if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType)
pImage->LoadJpeg(wsTexturePath.c_str(), nImageW, nImageH, oFrame.IsGrayScale());
else
pImage->LoadJpx(wsTexturePath.c_str(), nImageW, nImageH);
m_pDocument->AddImage(wsTexturePath, nAlpha, pImage);
}
}
else if (_CXIMAGE_FORMAT_WMF == oImageFormat.eFileType ||
_CXIMAGE_FORMAT_EMF == oImageFormat.eFileType ||
_CXIMAGE_FORMAT_SVM == oImageFormat.eFileType ||
_CXIMAGE_FORMAT_SVG == oImageFormat.eFileType)
{
// TODO: Реализовать отрисовку метафайлов по-нормальному
MetaFile::IMetaFile* pMeta = MetaFile::Create(pAppFonts);
pMeta->LoadFromFile(wsTexturePath.c_str());
double dL, dR, dT, dB;
m_oPath.GetBounds(dL, dT, dR, dB);
double dW = 300.0 * (dR - dL) / 72;
if (dW < 0) dW = -dW;
double dH = 300.0 * (dB - dT) / 72;
if (dH < 0) dH = -dH;
if (dW < 1) dW = 1;
if (dH < 1) dH = 1;
double dMax = 2000;
double dMin = 10;
if (dW > dMax || dH > dMax)
{
double dMaxSrc = (dW > dH) ? dW : dH;
dW *= (dMax / dMaxSrc);
dH *= (dMax / dMaxSrc);
}
if (dW < dMin) dW = dMin;
if (dH < dMin) dH = dMin;
std::wstring wsTempFile = GetTempFile(wsTempDirectory);
pMeta->ConvertToRaster(wsTempFile.c_str(), _CXIMAGE_FORMAT_PNG, (int)dW, (int)dH);
RELEASEOBJECT(pMeta);
Aggplus::CImage oImage(wsTempFile);
nImageW = abs((int)oImage.GetWidth());
nImageH = abs((int)oImage.GetHeight());
pImage = LoadImage(&oImage, 255);
m_pDocument->AddImage(wsTexturePath, nAlpha, pImage);
}
else
{
Aggplus::CImage oImage(wsTexturePath);
nImageW = abs((int)oImage.GetWidth());
nImageH = abs((int)oImage.GetHeight());
pImage = LoadImage(&oImage, 255);
m_pDocument->AddImage(wsTexturePath, nAlpha, pImage);
}
if (pImage)
{
if (0xFF != nAlpha && !bHasImage)
pImage->AddTransparency(nAlpha);
LONG lTextureMode = m_oBrush.GetTextureMode();
double dW = 10;
double dH = 10;
double dL, dR, dT, dB;
CBrushState::TBrushRect& oRect = m_oBrush.GetBrushRect();
if (!oRect.bUse)
{
m_oPath.GetBounds(dL, dT, dR, dB);
}
else
{
dL = MM_2_PT(oRect.dLeft);
dB = MM_2_PT(m_dPageHeight - oRect.dTop);
dR = MM_2_PT(oRect.dLeft + oRect.dWidth);
dT = MM_2_PT(m_dPageHeight - oRect.dTop - oRect.dHeight);
}
double dXStepSpacing = 0, dYStepSpacing = 0;
if (c_BrushTextureModeStretch == lTextureMode)
{
// Растягиваем картинку по размерам пата
dW = std::max(10.0, dR - dL);
dH = std::max(10.0, dB - dT);
// Чтобы избавиться от погрешностей из-за которых могут возникать полоски или обрезание картинки,
// удвоим расстрояние между соседними тайлами. Плохого тут нет, т.к. нам нужен всего 1 тайл
dXStepSpacing = dW;
dYStepSpacing = dH;
}
else
{
// Размеры картинки заданы в пикселях. Размеры тайла - это размеры картинки в пунктах.
dW = (double)nImageW * 72.0 / 96.0;
dH = (double)nImageH * 72.0 / 96.0;
dT = dB;
}
// Нам нужно, чтобы левый нижний угол границ нашего пата являлся точкой переноса для матрицы преобразования.
PdfWriter::CMatrix* pMatrix = m_pPage->GetTransform();
pMatrix->Apply(dL, dT);
PdfWriter::CMatrix oPatternMatrix = *pMatrix;
oPatternMatrix.x = dL;
oPatternMatrix.y = dT;
m_pPage->SetPatternColorSpace(m_pDocument->CreateImageTilePattern(dW, dH, pImage, &oPatternMatrix, PdfWriter::imagetilepatterntype_Default, dXStepSpacing, dYStepSpacing));
}
}
else if (c_BrushTypeHatch1 == lBrushType)
{
std::wstring wsHatchType = m_oBrush.GetTexturePath();
double dW = 8 * 72 / 96;
double dH = 8 * 72 / 96;
TColor oColor1 = m_oBrush.GetTColor1();
TColor oColor2 = m_oBrush.GetTColor2();
BYTE nAlpha1 = (BYTE)m_oBrush.GetAlpha1();
BYTE nAlpha2 = (BYTE)m_oBrush.GetAlpha2();
m_pPage->SetPatternColorSpace(m_pDocument->CreateHatchPattern(dW, dH, oColor1.r, oColor1.g, oColor1.b, nAlpha1, oColor2.r, oColor2.g, oColor2.b, nAlpha2, wsHatchType));
}
else if (c_BrushTypeRadialGradient == lBrushType || c_BrushTypeLinearGradient == lBrushType)
{
TColor* pGradientColors;
double* pPoints;
LONG lCount;
m_oBrush.GetGradientColors(pGradientColors, pPoints, lCount);
if (lCount > 0)
{
unsigned char* pColors = new unsigned char[3 * lCount];
unsigned char* pAlphas = new unsigned char[lCount];
if (pColors)
{
for (LONG lIndex = 0; lIndex < lCount; lIndex++)
{
pColors[3 * lIndex + 0] = pGradientColors[lIndex].r;
pColors[3 * lIndex + 1] = pGradientColors[lIndex].g;
pColors[3 * lIndex + 2] = pGradientColors[lIndex].b;
pAlphas[lIndex] = pGradientColors[lIndex].a;
}
if (c_BrushTypeLinearGradient == lBrushType)
{
double dX0, dY0, dX1, dY1;
m_oBrush.GetLinearGradientPattern(dX0, dY0, dX1, dY1);
m_pShading = m_pDocument->CreateAxialShading(m_pPage, MM_2_PT(dX0), MM_2_PT(m_dPageHeight - dY0), MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), pColors, pAlphas, pPoints, lCount, m_pShadingExtGrState);
}
else //if (c_BrushTypeRadialGradient == lBrushType)
{
double dX0, dY0, dR0, dX1, dY1, dR1;
m_oBrush.GetRadialGradientPattern(dX0, dY0, dR0, dX1, dY1, dR1);
m_pShading = m_pDocument->CreateRadialShading(m_pPage, MM_2_PT(dX0), MM_2_PT(m_dPageHeight - dY0), MM_2_PT(dR0), MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), MM_2_PT(dR1), pColors, pAlphas, pPoints, lCount, m_pShadingExtGrState);
}
delete[] pColors;
delete[] pAlphas;
}
}
}
*/
// else// if (c_BrushTypeSolid == lBrushType)
{
int nSize = -1;
double* dColor = m_pRenderer->m_oBrush.GetDColor2(nSize);
if (nSize == 1)
m_pPage->SetFillG(dColor[0]);
else if (nSize == 3)
m_pPage->SetFillRGB(dColor[0], dColor[1], dColor[2]);
else if (nSize == 4)
m_pPage->SetFillCMYK(dColor[0], dColor[1], dColor[2], dColor[3]);
// TODO ExtGState
// m_pPage->SetFillAlpha((unsigned char)m_pRenderer->m_oBrush.GetAlpha1());
}
}
void RedactOutputDev::UpdateAllClip(GfxState *pGState)
{
m_pRenderer->m_oCommandManager.Flush();
while (m_pRenderer->m_lClipDepth)
{
m_pPage->GrRestore();
m_pRenderer->m_lClipDepth--;
}
for (int i = 0; i < m_sStates.size(); i++)
{
GfxClip* pClip = m_sStates[i].m_pClip;
if (pClip)
for (int nIndex = 0, nClipCount = pClip->GetPathNum(); nIndex < nClipCount; nIndex++)
AddClip(pGState, &m_sStates[i], nIndex);
}
updateFont(pGState);
}
void RedactOutputDev::AddClip(GfxState* pGState, GfxRedactState* pState, int nIndex) void RedactOutputDev::AddClip(GfxState* pGState, GfxRedactState* pState, int nIndex)
{ {
m_pRenderer->m_oCommandManager.Flush();
DoStateOp();
GfxClip* pClip = pState->m_pClip; GfxClip* pClip = pState->m_pClip;
GfxPath* pPath = pClip->GetPath(nIndex); GfxPath* pPath = pClip->GetPath(nIndex);
int nClipFlag = pClip->GetClipFlag(nIndex);; int nClipFlag = pClip->GetClipFlag(nIndex);;
@ -1502,11 +1196,24 @@ void RedactOutputDev::AddClip(GfxState* pGState, GfxRedactState* pState, int nIn
GfxClipMatrix oMatrix = pClip->m_vMatrix[nIndex]; GfxClipMatrix oMatrix = pClip->m_vMatrix[nIndex];
double pMatrix[6] = { oMatrix.dA, oMatrix.dB, oMatrix.dC, oMatrix.dD, oMatrix.dE, oMatrix.dF }; double pMatrix[6] = { oMatrix.dA, oMatrix.dB, oMatrix.dC, oMatrix.dD, oMatrix.dE, oMatrix.dF };
DoPath(pGState, pPath, pMatrix); DoPath(pGState, pPath, pMatrix);
m_pRenderer->m_oCommandManager.Flush();
m_pPage->GrSave();
m_pRenderer->m_lClipDepth++;
UpdateTransform(); UpdateTransform();
m_pRenderer->m_oPath.Clip(m_pPage, c_nClipRegionTypeEvenOdd & m_pRenderer->m_lClipMode); m_pRenderer->m_oPath.Clip(m_pPage, c_nClipRegionTypeEvenOdd & m_pRenderer->m_lClipMode);
m_pRenderer->m_oPath.Clear(); m_pRenderer->m_oPath.Clear();
} }
void RedactOutputDev::DoStateOp()
{
if (m_sStates.empty() || m_sStates.back().m_arrOp.empty())
return;
CStream* pStream = m_pPage->GetStream();
for (int i = 0; i < m_sStates.back().m_arrOp.size(); ++i)
{
auto arrOp = m_sStates.back().m_arrOp;
pStream->WriteStr(arrOp[i].first.c_str());
pStream->WriteChar(' ');
pStream->WriteStr(arrOp[i].second.c_str());
pStream->WriteStr("\012");
}
m_sStates.back().m_arrOp.clear();
}
} }

View File

@ -156,7 +156,11 @@ namespace PdfWriter
virtual GBool useNameOp() override; virtual GBool useNameOp() override;
virtual void setExtGState(const char* name) override; virtual void setExtGState(const char* name) override;
virtual void setFillColorSpace(const char* name) override; virtual void setFillColorSpace(const char* name) override;
virtual void setFillColor(Object* args, int numArgs) override;
virtual void setFillColorN(Object* args, int numArgs) override; virtual void setFillColorN(Object* args, int numArgs) override;
virtual void setStrokeColorSpace(const char* name) override;
virtual void setStrokeColor(Object* args, int numArgs) override;
virtual void setStrokeColorN(Object* args, int numArgs) override;
virtual void setShading(GfxState *state, const char* name) override; virtual void setShading(GfxState *state, const char* name) override;
//----- image drawing //----- image drawing
virtual void drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; virtual void drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override;
@ -198,10 +202,8 @@ namespace PdfWriter
void DoTransform(double* pMatrix, double* pdShiftX, double* pdShiftY, bool bActual = false); void DoTransform(double* pMatrix, double* pdShiftX, double* pdShiftY, bool bActual = false);
void DrawPath(const LONG& lType); void DrawPath(const LONG& lType);
void UpdateTransform(); void UpdateTransform();
void UpdatePen();
void UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::wstring& wsTempDirectory);
void UpdateAllClip(GfxState *pGState);
void AddClip(GfxState* pGState, GfxRedactState* pState, int nIndex); void AddClip(GfxState* pGState, GfxRedactState* pState, int nIndex);
void DoStateOp();
XRef* m_pXref; XRef* m_pXref;
std::vector<double> m_arrQuadPoints; std::vector<double> m_arrQuadPoints;
@ -212,7 +214,7 @@ namespace PdfWriter
CPage* m_pPage; CPage* m_pPage;
double m_arrMatrix[6]; double m_arrMatrix[6];
BYTE m_nRI; bool m_bUpdateAll;
std::deque<GfxRedactState> m_sStates; std::deque<GfxRedactState> m_sStates;
}; };
} }

View File

@ -125,41 +125,7 @@ void CCommandManager::Flush()
} }
} }
if (!pText->GetName().empty()) if (lTextColor != pText->GetColor())
{
int nColorSize2;
double* dColor2 = pText->GetDColor2(nColorSize2);
if (nColorSize2 == 1 && (nColorSize != nColorSize2 || dColor[0] != dColor2[0]))
{
oTextLine.Flush(pPage);
nColorSize = nColorSize2;
dColor[0] = dColor2[0];
pPage->SetFillG(dColor[0]);
pPage->SetStrokeG(dColor[0]);
}
else if (nColorSize2 == 3 && (nColorSize != nColorSize2 || dColor[0] != dColor2[0] || dColor[1] != dColor2[1] || dColor[2] != dColor2[2]))
{
oTextLine.Flush(pPage);
nColorSize = nColorSize2;
dColor[0] = dColor2[0];
dColor[1] = dColor2[1];
dColor[2] = dColor2[2];
pPage->SetFillRGB(dColor[0], dColor[1], dColor[2]);
pPage->SetStrokeRGB(dColor[0], dColor[1], dColor[2]);
}
else if (nColorSize2 == 4 && (nColorSize != nColorSize2 || dColor[0] != dColor2[0] || dColor[1] != dColor2[1] || dColor[2] != dColor2[2] || dColor[3] != dColor2[3]))
{
oTextLine.Flush(pPage);
nColorSize = nColorSize2;
dColor[0] = dColor2[0];
dColor[1] = dColor2[1];
dColor[2] = dColor2[2];
dColor[3] = dColor2[3];
pPage->SetFillCMYK(dColor[0], dColor[1], dColor[2], dColor[3]);
pPage->SetStrokeCMYK(dColor[0], dColor[1], dColor[2], dColor[3]);
}
}
else if (lTextColor != pText->GetColor())
{ {
oTextLine.Flush(pPage); oTextLine.Flush(pPage);
lTextColor = pText->GetColor(); lTextColor = pText->GetColor();

View File

@ -79,8 +79,6 @@ public:
m_dCharSpace = 0; m_dCharSpace = 0;
m_dHorScaling = 100; m_dHorScaling = 100;
m_nMode = (int)PdfWriter::textrenderingmode_Fill; m_nMode = (int)PdfWriter::textrenderingmode_Fill;
m_nColor2Size = 1;
m_dColor2[0] = 0;
m_dRise = 0; m_dRise = 0;
m_dWordSpace = 0; m_dWordSpace = 0;
m_dWidth = -1; m_dWidth = -1;
@ -158,14 +156,6 @@ public:
{ {
m_sPUA = sPUA; m_sPUA = sPUA;
} }
inline void SetDColor2(int nSize, double d1 = 0, double d2 = 0, double d3 = 0, double d4 = 0)
{
m_nColor2Size = nSize;
m_dColor2[0] = d1;
m_dColor2[1] = d2;
m_dColor2[2] = d3;
m_dColor2[3] = d4;
}
inline void SetRise(const double& dRise) inline void SetRise(const double& dRise)
{ {
m_dRise = dRise; m_dRise = dRise;
@ -226,11 +216,6 @@ public:
{ {
return m_sPUA; return m_sPUA;
} }
inline double* GetDColor2(int& nSize)
{
nSize = m_nColor2Size;
return m_dColor2;
}
inline double GetRise() inline double GetRise()
{ {
return m_dRise; return m_dRise;
@ -266,8 +251,6 @@ private:
int m_nMode; int m_nMode;
double m_dHorScaling; double m_dHorScaling;
std::string m_sPUA; std::string m_sPUA;
double m_dColor2[4];
int m_nColor2Size;
double m_dRise; double m_dRise;
double m_dWordSpace; double m_dWordSpace;
std::wstring m_sName; std::wstring m_sName;

View File

@ -1489,6 +1489,11 @@ void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) {
" in uncolored Type 3 char or tiling pattern"); " in uncolored Type 3 char or tiling pattern");
return; return;
} }
if (out->useNameOp())
{
out->setStrokeColorSpace(args[0].getName());
return;
}
state->setStrokePattern(NULL); state->setStrokePattern(NULL);
res->lookupColorSpace(args[0].getName(), &obj); res->lookupColorSpace(args[0].getName(), &obj);
if (obj.isNull()) { if (obj.isNull()) {
@ -1528,6 +1533,11 @@ void Gfx::opSetFillColor(Object args[], int numArgs) {
"Incorrect number of arguments in 'sc' command"); "Incorrect number of arguments in 'sc' command");
return; return;
} }
if (out->useNameOp())
{
out->setFillColor(args, numArgs);
return;
}
state->setFillPattern(NULL); state->setFillPattern(NULL);
for (i = 0; i < numArgs; ++i) { for (i = 0; i < numArgs; ++i) {
color.c[i] = dblToCol(args[i].getNum()); color.c[i] = dblToCol(args[i].getNum());
@ -1549,6 +1559,11 @@ void Gfx::opSetStrokeColor(Object args[], int numArgs) {
"Incorrect number of arguments in 'SC' command"); "Incorrect number of arguments in 'SC' command");
return; return;
} }
if (out->useNameOp())
{
out->setStrokeColor(args, numArgs);
return;
}
state->setStrokePattern(NULL); state->setStrokePattern(NULL);
for (i = 0; i < numArgs; ++i) { for (i = 0; i < numArgs; ++i) {
color.c[i] = dblToCol(args[i].getNum()); color.c[i] = dblToCol(args[i].getNum());
@ -1625,6 +1640,11 @@ void Gfx::opSetStrokeColorN(Object args[], int numArgs) {
" in uncolored Type 3 char or tiling pattern"); " in uncolored Type 3 char or tiling pattern");
return; return;
} }
if (out->useNameOp())
{
out->setStrokeColorN(args, numArgs);
return;
}
if (state->getStrokeColorSpace()->getMode() == csPattern) { if (state->getStrokeColorSpace()->getMode() == csPattern) {
if (numArgs == 0 || !args[numArgs-1].isName()) { if (numArgs == 0 || !args[numArgs-1].isName()) {
error(errSyntaxError, getPos(), error(errSyntaxError, getPos(),

View File

@ -193,7 +193,11 @@ public:
virtual GBool useNameOp() { return gFalse; } virtual GBool useNameOp() { return gFalse; }
virtual void setExtGState(const char* name) {} virtual void setExtGState(const char* name) {}
virtual void setFillColorSpace(const char* name) {} virtual void setFillColorSpace(const char* name) {}
virtual void setFillColor(Object* args, int numArgs) {}
virtual void setFillColorN(Object* args, int numArgs) {} virtual void setFillColorN(Object* args, int numArgs) {}
virtual void setStrokeColorSpace(const char* name) {}
virtual void setStrokeColor(Object* args, int numArgs) {}
virtual void setStrokeColorN(Object* args, int numArgs) {}
virtual void setShading(GfxState *state, const char* name) {} virtual void setShading(GfxState *state, const char* name) {}
//----- image drawing //----- image drawing