mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Merge remote-tracking branch 'origin/develop' into feature/pdf-link
This commit is contained in:
@ -203,15 +203,24 @@ bool GlobalParamsAdaptor::InRedact(double dX, double dY)
|
||||
double x4 = m_arrRedactBox[i + 4];
|
||||
double y4 = m_arrRedactBox[i + 5];
|
||||
|
||||
if (x1 == x2 && x2 == x3 && x3 == x4 && y1 == y2 && y2 == y3 && y3 == y4)
|
||||
{
|
||||
if (dX == x1 && dY == y1)
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Проверяем знаки векторных произведений для всех сторон
|
||||
double cross1 = crossProduct(x1, y1, x2, y2, dX, dY);
|
||||
double cross2 = crossProduct(x2, y2, x3, y3, dX, dY);
|
||||
double cross3 = crossProduct(x3, y3, x4, y4, dX, dY);
|
||||
double cross4 = crossProduct(x4, y4, x1, y1, dX, dY);
|
||||
|
||||
bool allPositive = (cross1 >= 0 && cross2 >= 0 && cross3 >= 0 && cross4 >= 0);
|
||||
bool allNegative = (cross1 <= 0 && cross2 <= 0 && cross3 <= 0 && cross4 <= 0);
|
||||
|
||||
// Точка внутри, если все векторные произведения имеют одинаковый знак
|
||||
if ((cross1 >= 0 && cross2 >= 0 && cross3 >= 0 && cross4 >= 0) ||
|
||||
(cross1 <= 0 && cross2 <= 0 && cross3 <= 0 && cross4 <= 0))
|
||||
if ((allPositive || allNegative) && !(cross1 == 0 && cross2 == 0 && cross3 == 0 && cross4 == 0))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -534,6 +534,45 @@ CAnnot::CBorderType* getBorder(Object* oBorder, bool bBSorBorder)
|
||||
|
||||
return pBorderType;
|
||||
}
|
||||
std::string GetRCFromDS(const std::string& sDS, Object* pContents, const std::vector<double>& arrCFromDA)
|
||||
{
|
||||
NSStringUtils::CStringBuilder oRC;
|
||||
|
||||
oRC += L"<?xml version=\"1.0\"?><body xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\" xfa:APIVersion=\"Acrobat:23.8.0\" xfa:spec=\"2.0.2\"><p dir=\"ltr\"><span style=\"";
|
||||
if (sDS.find("font-family") == std::string::npos)
|
||||
oRC += L"font-family:Helvetica;";
|
||||
if (sDS.find("font-size") == std::string::npos)
|
||||
oRC += L"font-size:14.0pt;";
|
||||
if (sDS.find("text-align") == std::string::npos)
|
||||
oRC += L"text-align:left;";
|
||||
if (sDS.find("font-weight") == std::string::npos)
|
||||
oRC += L"font-weight:normal;";
|
||||
if (sDS.find("font-style") == std::string::npos)
|
||||
oRC += L"font-style:normal;";
|
||||
if (sDS.find("text-decoration") == std::string::npos)
|
||||
oRC += L"text-decoration:none;";
|
||||
if (sDS.find("color") == std::string::npos)
|
||||
{
|
||||
oRC += L"color:";
|
||||
if (arrCFromDA.size() == 3)
|
||||
oRC.WriteHexColor3((unsigned char)(arrCFromDA[0] * 255.0),
|
||||
(unsigned char)(arrCFromDA[1] * 255.0),
|
||||
(unsigned char)(arrCFromDA[2] * 255.0));
|
||||
else
|
||||
oRC += L"#000000";
|
||||
}
|
||||
oRC += (UTF8_TO_U(sDS));
|
||||
|
||||
oRC += L"\">";
|
||||
TextString* s = new TextString(pContents->getString());
|
||||
std::wstring wsContents = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());
|
||||
delete s;
|
||||
oRC.WriteEncodeXmlString(wsContents);
|
||||
oRC += L"</span></p></body>";
|
||||
|
||||
std::wstring wsRC = oRC.GetData();
|
||||
return U_TO_UTF8(wsRC);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Fonts
|
||||
@ -656,29 +695,43 @@ std::map<std::wstring, std::wstring> CAnnotFonts::GetAllFonts(PDFDoc* pdfDoc, NS
|
||||
}
|
||||
oSubtype.free();
|
||||
|
||||
std::string sRC;
|
||||
Object oObj;
|
||||
if (!oAnnot.dictLookup("RC", &oObj)->isString())
|
||||
{
|
||||
oObj.free();
|
||||
if (oAnnot.dictLookup("AP", &oObj)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength())
|
||||
if (oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength())
|
||||
{
|
||||
const unsigned char* pData14 = NULL;
|
||||
unsigned int nSize14 = 0;
|
||||
std::wstring wsFontName = L"Helvetica";
|
||||
NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage();
|
||||
if (pMemoryStorage && !pMemoryStorage->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14))
|
||||
pMemoryStorage->Add(wsFontName, (BYTE*)pData14, nSize14, false);
|
||||
mFonts[L"Helvetica"] = L"Helvetica";
|
||||
}
|
||||
oAnnot.free(); oObj.free();
|
||||
continue;
|
||||
}
|
||||
oAnnot.free();
|
||||
std::string sDS;
|
||||
Object oObj2;
|
||||
if (oAnnot.dictLookup("DS", &oObj2)->isString())
|
||||
{
|
||||
TextString* s = new TextString(oObj2.getString());
|
||||
sDS = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
|
||||
delete s;
|
||||
}
|
||||
oObj2.free();
|
||||
|
||||
TextString* s = new TextString(oObj.getString());
|
||||
std::string sRC = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
|
||||
delete s;
|
||||
oObj.free();
|
||||
sRC = GetRCFromDS(sDS, &oObj, {});
|
||||
if (sRC.find("font-family:Helvetica") != std::string::npos)
|
||||
{
|
||||
const unsigned char* pData14 = NULL;
|
||||
unsigned int nSize14 = 0;
|
||||
std::wstring wsFontName = L"Helvetica";
|
||||
NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage();
|
||||
if (pMemoryStorage && !pMemoryStorage->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14))
|
||||
pMemoryStorage->Add(wsFontName, (BYTE*)pData14, nSize14, false);
|
||||
mFonts[L"Helvetica"] = L"Helvetica";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TextString* s = new TextString(oObj.getString());
|
||||
sRC = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
|
||||
delete s;
|
||||
}
|
||||
oObj.free(); oAnnot.free();
|
||||
|
||||
Object oAnnotRef;
|
||||
oAnnots.arrayGetNF(i, &oAnnotRef);
|
||||
@ -1820,6 +1873,11 @@ CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nS
|
||||
m_nState = 5;
|
||||
}
|
||||
oObj.free();
|
||||
|
||||
// Text аннотация с IRT не отображается
|
||||
if (m_unFlags & (1 << 5))
|
||||
m_unAFlags &= ~(1 << 6);
|
||||
|
||||
oAnnot.free();
|
||||
}
|
||||
|
||||
@ -2240,27 +2298,9 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex
|
||||
}
|
||||
oObj.free();
|
||||
|
||||
if (oAnnot.dictLookup("AP", &oObj)->isNull() && oAnnot.dictLookup("RC", &oObj2)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength())
|
||||
if (oAnnot.dictLookup("RC", &oObj2)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength())
|
||||
{
|
||||
NSStringUtils::CStringBuilder oRC;
|
||||
|
||||
oRC += L"<?xml version=\"1.0\"?><body xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\" xfa:APIVersion=\"Acrobat:23.8.0\" xfa:spec=\"2.0.2\"><p dir=\"ltr\"><span style=\"font-size:14.0pt;font-family:Helvetica;text-align:left;color:";
|
||||
if (m_arrCFromDA.size() == 3)
|
||||
oRC.WriteHexColor3((unsigned char)(m_arrCFromDA[0] * 255.0),
|
||||
(unsigned char)(m_arrCFromDA[1] * 255.0),
|
||||
(unsigned char)(m_arrCFromDA[2] * 255.0));
|
||||
else
|
||||
oRC += L"#000000";
|
||||
|
||||
oRC += L"\">";
|
||||
TextString* s = new TextString(oObj.getString());
|
||||
std::wstring wsContents = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());
|
||||
delete s;
|
||||
oRC.WriteEncodeXmlString(wsContents);
|
||||
oRC += L"</span></p></body>";
|
||||
|
||||
std::wstring wsRC = oRC.GetData();
|
||||
m_arrRC = CAnnotMarkup::ReadRC(U_TO_UTF8(wsRC));
|
||||
m_arrRC = CAnnotMarkup::ReadRC(GetRCFromDS(m_sDS, &oObj, m_arrCFromDA));
|
||||
if (m_arrRC.empty())
|
||||
m_unFlags &= ~(1 << 3);
|
||||
else
|
||||
|
||||
@ -1696,6 +1696,7 @@ namespace PdfReader
|
||||
m_pRendererOut->NewPDF(gfx->getDoc()->getXRef());
|
||||
|
||||
Gfx* m_gfx = new Gfx(gfx->getDoc(), m_pRendererOut, -1, pResourcesDict, dDpiX, dDpiY, &box, NULL, 0);
|
||||
m_gfx->takeContentStreamStack(gfx);
|
||||
m_gfx->display(pStream);
|
||||
|
||||
pFrame->ClearNoAttack();
|
||||
@ -2707,7 +2708,7 @@ namespace PdfReader
|
||||
RELEASEOBJECT(pCommand);
|
||||
}
|
||||
}
|
||||
void RendererOutputDev::drawImageMask(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate)
|
||||
void RendererOutputDev::drawImageMask(GfxState* pGState, Gfx *gfx, Object* pRef, Stream* pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate)
|
||||
{
|
||||
if (m_bDrawOnlyText || pGState->getFillColorSpace()->isNonMarking())
|
||||
return;
|
||||
@ -2783,7 +2784,7 @@ namespace PdfReader
|
||||
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);
|
||||
m_pRenderer->DrawImage(&oImage, dShiftX, dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1));
|
||||
}
|
||||
void RendererOutputDev::setSoftMaskFromImageMask(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate)
|
||||
void RendererOutputDev::setSoftMaskFromImageMask(GfxState* pGState, Gfx *gfx, Object* pRef, Stream* pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate)
|
||||
{
|
||||
if (m_bDrawOnlyText || pGState->getFillColorSpace()->isNonMarking())
|
||||
return;
|
||||
@ -2886,7 +2887,87 @@ namespace PdfReader
|
||||
}
|
||||
return isMask;
|
||||
}
|
||||
BYTE* BufferFromImageStream(GfxState* pGState, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, int* pMaskColors)
|
||||
{
|
||||
int nBufferSize = 4 * nWidth * nHeight;
|
||||
if (nBufferSize < 1)
|
||||
return NULL;
|
||||
|
||||
BYTE* pBufferPtr = new(std::nothrow) BYTE[nBufferSize];
|
||||
if (!pBufferPtr)
|
||||
return NULL;
|
||||
|
||||
int nComponentsCount = pColorMap->getNumPixelComps();
|
||||
BYTE unAlpha = std::min(255, std::max(0, int(pGState->getFillOpacity() * 255)));
|
||||
|
||||
// Пишем данные в pBufferPtr
|
||||
ImageStream* pImageStream = new ImageStream(pStream, nWidth, nComponentsCount, pColorMap->getBits());
|
||||
pImageStream->reset();
|
||||
|
||||
int nComps = pImageStream->getComps();
|
||||
int nCheckWidth = std::min(nWidth, pImageStream->getVals() / nComps);
|
||||
GfxRenderingIntent intent = pGState->getRenderingIntent();
|
||||
|
||||
// fast realization for some colorspaces (for wasm module)
|
||||
int nColorMapType = pColorMap->getFillType();
|
||||
GfxColorComp** pColorMapLookup = pColorMap->getLookup();
|
||||
if (!pColorMapLookup)
|
||||
nColorMapType = 0;
|
||||
|
||||
for (int nY = nHeight - 1; nY >= 0; --nY)
|
||||
{
|
||||
BYTE* pLine = pImageStream->getLine();
|
||||
BYTE* pLineDst = pBufferPtr + 4 * nWidth * nY;
|
||||
|
||||
if (!pLine)
|
||||
{
|
||||
memset(pLineDst, 0, 4 * nWidth);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int nX = 0; nX < nCheckWidth; ++nX)
|
||||
{
|
||||
if (2 == nColorMapType)
|
||||
{
|
||||
pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]]));
|
||||
pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]]));
|
||||
pLineDst[0] = colToByte(clip01(pColorMapLookup[2][pLine[2]]));
|
||||
}
|
||||
else if (1 == nColorMapType)
|
||||
{
|
||||
pLineDst[0] = pLineDst[1] = pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]]));
|
||||
}
|
||||
else if (3 == nColorMapType)
|
||||
{
|
||||
pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]]));
|
||||
pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]]));
|
||||
pLineDst[0] = colToByte(clip01(pColorMapLookup[2][pLine[2]]));
|
||||
pLineDst[3] = colToByte(clip01(pColorMapLookup[3][pLine[3]]));
|
||||
}
|
||||
else
|
||||
{
|
||||
GfxRGB oRGB;
|
||||
pColorMap->getRGB(pLine, &oRGB, intent);
|
||||
pLineDst[0] = colToByte(oRGB.b);
|
||||
pLineDst[1] = colToByte(oRGB.g);
|
||||
pLineDst[2] = colToByte(oRGB.r);
|
||||
}
|
||||
|
||||
if (pMaskColors && CheckMask(nComponentsCount, pMaskColors, pLine))
|
||||
pLineDst[3] = 0;
|
||||
else if (3 != nColorMapType)
|
||||
pLineDst[3] = unAlpha;
|
||||
|
||||
pLine += nComps;
|
||||
pLineDst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
pImageStream->close();
|
||||
delete pImageStream;
|
||||
|
||||
return pBufferPtr;
|
||||
}
|
||||
bool RendererOutputDev::ReadImage(Aggplus::CImage* pImageRes, Object* pRef, Stream* pStream)
|
||||
{
|
||||
Object oIm;
|
||||
@ -2924,7 +3005,7 @@ namespace PdfReader
|
||||
RELEASEARRAYOBJECTS(pBuffer);
|
||||
return false;
|
||||
}
|
||||
void RendererOutputDev::drawImage(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, int* pMaskColors, GBool bInlineImg, GBool interpolate)
|
||||
void RendererOutputDev::drawImage(GfxState* pGState, Gfx *gfx, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, int* pMaskColors, GBool bInlineImg, GBool interpolate)
|
||||
{
|
||||
if (m_bDrawOnlyText)
|
||||
return;
|
||||
@ -2937,80 +3018,10 @@ namespace PdfReader
|
||||
// Чтение jpeg через cximage происходит быстрее чем через xpdf на ~40%
|
||||
if (pMaskColors || unAlpha != 255 || (nSK != strDCT || nComponentsCount != 3 || !ReadImage(&oImage, pRef, pStream)))
|
||||
{
|
||||
int nBufferSize = 4 * nWidth * nHeight;
|
||||
if (nBufferSize < 1)
|
||||
return;
|
||||
|
||||
BYTE* pBufferPtr = new(std::nothrow) BYTE[nBufferSize];
|
||||
BYTE* pBufferPtr = BufferFromImageStream(pGState, pStream, nWidth, nHeight, pColorMap, pMaskColors);
|
||||
if (!pBufferPtr)
|
||||
return;
|
||||
|
||||
// Пишем данные в pBufferPtr
|
||||
ImageStream* pImageStream = new ImageStream(pStream, nWidth, nComponentsCount, pColorMap->getBits());
|
||||
pImageStream->reset();
|
||||
|
||||
int nComps = pImageStream->getComps();
|
||||
int nCheckWidth = std::min(nWidth, pImageStream->getVals() / nComps);
|
||||
GfxRenderingIntent intent = pGState->getRenderingIntent();
|
||||
|
||||
// fast realization for some colorspaces (for wasm module)
|
||||
int nColorMapType = pColorMap->getFillType();
|
||||
GfxColorComp** pColorMapLookup = pColorMap->getLookup();
|
||||
if (!pColorMapLookup)
|
||||
nColorMapType = 0;
|
||||
|
||||
for (int nY = nHeight - 1; nY >= 0; --nY)
|
||||
{
|
||||
BYTE* pLine = pImageStream->getLine();
|
||||
BYTE* pLineDst = pBufferPtr + 4 * nWidth * nY;
|
||||
|
||||
if (!pLine)
|
||||
{
|
||||
memset(pLineDst, 0, 4 * nWidth);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int nX = 0; nX < nCheckWidth; ++nX)
|
||||
{
|
||||
if (2 == nColorMapType)
|
||||
{
|
||||
pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]]));
|
||||
pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]]));
|
||||
pLineDst[0] = colToByte(clip01(pColorMapLookup[2][pLine[2]]));
|
||||
}
|
||||
else if (1 == nColorMapType)
|
||||
{
|
||||
pLineDst[0] = pLineDst[1] = pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]]));
|
||||
}
|
||||
else if (3 == nColorMapType)
|
||||
{
|
||||
pLineDst[2] = colToByte(clip01(pColorMapLookup[0][pLine[0]]));
|
||||
pLineDst[1] = colToByte(clip01(pColorMapLookup[1][pLine[1]]));
|
||||
pLineDst[0] = colToByte(clip01(pColorMapLookup[2][pLine[2]]));
|
||||
pLineDst[3] = colToByte(clip01(pColorMapLookup[3][pLine[3]]));
|
||||
}
|
||||
else
|
||||
{
|
||||
GfxRGB oRGB;
|
||||
pColorMap->getRGB(pLine, &oRGB, intent);
|
||||
pLineDst[0] = colToByte(oRGB.b);
|
||||
pLineDst[1] = colToByte(oRGB.g);
|
||||
pLineDst[2] = colToByte(oRGB.r);
|
||||
}
|
||||
|
||||
if (pMaskColors && CheckMask(nComponentsCount, pMaskColors, pLine))
|
||||
pLineDst[3] = 0;
|
||||
else if (3 != nColorMapType)
|
||||
pLineDst[3] = unAlpha;
|
||||
|
||||
pLine += nComps;
|
||||
pLineDst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
pImageStream->close();
|
||||
delete pImageStream;
|
||||
|
||||
oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth);
|
||||
}
|
||||
|
||||
@ -3031,13 +3042,13 @@ namespace PdfReader
|
||||
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);
|
||||
m_pRenderer->DrawImage(&oImage, dShiftX, dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1));
|
||||
}
|
||||
void RendererOutputDev::drawMaskedImage(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, Object* pStreamRef, Stream* pMaskStream, int nMaskWidth, int nMaskHeight, GBool bMaskInvert, GBool interpolate)
|
||||
void RendererOutputDev::drawMaskedImage(GfxState* pGState, Gfx *gfx, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, Object* pStreamRef, Stream* pMaskStream, int nMaskWidth, int nMaskHeight, GBool bMaskInvert, GBool interpolate)
|
||||
{
|
||||
if (m_bDrawOnlyText)
|
||||
return;
|
||||
|
||||
if (nMaskWidth <= 0 || nMaskHeight <= 0)
|
||||
drawImage(pGState, pRef, pStream, nWidth, nHeight, pColorMap, NULL, false, interpolate);
|
||||
drawImage(pGState, gfx, pRef, pStream, nWidth, nHeight, pColorMap, NULL, false, interpolate);
|
||||
|
||||
if (nMaskWidth > nWidth || nMaskHeight > nHeight)
|
||||
{
|
||||
@ -3054,7 +3065,7 @@ namespace PdfReader
|
||||
maskDecode.arrayAdd(&decodeHigh);
|
||||
maskColorMap = new GfxImageColorMap(1, &maskDecode, new GfxDeviceGrayColorSpace());
|
||||
maskDecode.free();
|
||||
drawSoftMaskedImage(pGState, pRef, pStream, nWidth, nHeight,
|
||||
drawSoftMaskedImage(pGState, gfx, pRef, pStream, nWidth, nHeight,
|
||||
pColorMap, pStreamRef, pMaskStream, nMaskWidth, nMaskHeight, maskColorMap, NULL, interpolate);
|
||||
delete maskColorMap;
|
||||
return;
|
||||
@ -3176,7 +3187,7 @@ namespace PdfReader
|
||||
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);
|
||||
m_pRenderer->DrawImage(&oImage, dShiftX, dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1));
|
||||
}
|
||||
void RendererOutputDev::drawSoftMaskedImage(GfxState* pGState, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, Object* maskRef, Stream* pMaskStream, int nMaskWidth, int nMaskHeight, GfxImageColorMap* pMaskColorMap, double* pMatteColor, GBool interpolate)
|
||||
void RendererOutputDev::drawSoftMaskedImage(GfxState* pGState, Gfx *gfx, Object* pRef, Stream* pStream, int nWidth, int nHeight, GfxImageColorMap* pColorMap, Object* maskRef, Stream* pMaskStream, int nMaskWidth, int nMaskHeight, GfxImageColorMap* pMaskColorMap, double* pMatteColor, GBool interpolate)
|
||||
{
|
||||
if (m_bDrawOnlyText)
|
||||
return;
|
||||
@ -3190,33 +3201,9 @@ namespace PdfReader
|
||||
|
||||
if (nComponentsCount != 3 || pStream->getKind() != strDCT || !ReadImage(&oImage, pRef, pStream))
|
||||
{
|
||||
BYTE* pBufferPtr = new(std::nothrow) BYTE[nBufferSize];
|
||||
BYTE* pBufferPtr = BufferFromImageStream(pGState, pStream, nWidth, nHeight, pColorMap, NULL);
|
||||
if (!pBufferPtr)
|
||||
return;
|
||||
|
||||
// Пишем данные в pBufferPtr
|
||||
ImageStream* pImageStream = new ImageStream(pStream, nWidth, pColorMap->getNumPixelComps(), pColorMap->getBits());
|
||||
pImageStream->reset();
|
||||
|
||||
BYTE unPixel[4] = { 0, 0, 0, 0 };
|
||||
for (int nY = nHeight - 1; nY >= 0; --nY)
|
||||
{
|
||||
int nIndex = 4 * nY * nWidth;
|
||||
for (int nX = 0; nX < nWidth; ++nX)
|
||||
{
|
||||
pImageStream->getPixel(unPixel);
|
||||
GfxRGB oRGB;
|
||||
pColorMap->getRGB(unPixel, &oRGB, gfxRenderingIntentAbsoluteColorimetric);
|
||||
pBufferPtr[nIndex + 0] = colToByte(oRGB.b);
|
||||
pBufferPtr[nIndex + 1] = colToByte(oRGB.g);
|
||||
pBufferPtr[nIndex + 2] = colToByte(oRGB.r);
|
||||
pBufferPtr[nIndex + 3] = 255;
|
||||
|
||||
nIndex += 4;
|
||||
}
|
||||
}
|
||||
delete pImageStream;
|
||||
|
||||
oImage.Create(pBufferPtr, nWidth, nHeight, -4 * nWidth);
|
||||
}
|
||||
|
||||
@ -3331,16 +3318,54 @@ namespace PdfReader
|
||||
ImageStream* pSMaskStream = new ImageStream(pMaskStream, nMaskWidth, pMaskColorMap->getNumPixelComps(), pMaskColorMap->getBits());
|
||||
pSMaskStream->reset();
|
||||
|
||||
// Быстрая реализация для масок
|
||||
int nMaskColorMapType = pMaskColorMap->getFillType();
|
||||
GfxColorComp** pMaskColorMapLookup = pMaskColorMap->getLookup();
|
||||
if (!pMaskColorMapLookup)
|
||||
nMaskColorMapType = 0;
|
||||
int nMaskComps = pSMaskStream->getComps();
|
||||
int nMaskCheckWidth = std::min(nMaskWidth, pSMaskStream->getVals() / nMaskComps);
|
||||
|
||||
BYTE unAlpha = 0;
|
||||
for (int nY = nMaskHeight - 1; nY >= 0; --nY)
|
||||
{
|
||||
BYTE* pMaskLine = pSMaskStream->getLine();
|
||||
int nIndex = 4 * nY * nMaskWidth;
|
||||
for (int nX = 0; nX < nMaskWidth; ++nX)
|
||||
if (!pMaskLine)
|
||||
{
|
||||
pSMaskStream->getPixel(&unAlpha);
|
||||
GfxGray oGray;
|
||||
pMaskColorMap->getGray(&unAlpha, &oGray, GfxRenderingIntent::gfxRenderingIntentAbsoluteColorimetric);
|
||||
pBufferPtr[nIndex + 3] = (BYTE)(colToByte(oGray) * dAlphaKoef);
|
||||
// Заполняем прозрачностью, если линия не прочитана
|
||||
for (int nX = 0; nX < nMaskWidth; ++nX)
|
||||
{
|
||||
pBufferPtr[nIndex + 3] = 0;
|
||||
nIndex += 4;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int nX = 0; nX < nMaskCheckWidth; ++nX)
|
||||
{
|
||||
BYTE unAlpha = 0;
|
||||
|
||||
// Оптимизированные случаи для разных цветовых пространств
|
||||
if (1 == nMaskColorMapType)
|
||||
{
|
||||
unAlpha = colToByte(clip01(pMaskColorMapLookup[0][pMaskLine[0]]));
|
||||
}
|
||||
else if (2 == nMaskColorMapType || 3 == nMaskColorMapType)
|
||||
{
|
||||
unAlpha = colToByte(clip01(0.3 * pMaskColorMapLookup[0][pMaskLine[0]] +
|
||||
0.59 * pMaskColorMapLookup[1][pMaskLine[1]] +
|
||||
0.11 * pMaskColorMapLookup[2][pMaskLine[2]] + 0.5));
|
||||
}
|
||||
else
|
||||
{
|
||||
GfxGray oGray;
|
||||
pMaskColorMap->getGray(pMaskLine, &oGray, GfxRenderingIntent::gfxRenderingIntentAbsoluteColorimetric);
|
||||
unAlpha = colToByte(oGray);
|
||||
}
|
||||
|
||||
pBufferPtr[nIndex + 3] = (BYTE)(unAlpha * dAlphaKoef);
|
||||
pMaskLine += nMaskComps;
|
||||
nIndex += 4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,12 +223,12 @@ namespace PdfReader
|
||||
virtual void endMarkedContent(GfxState *state) override;
|
||||
//----- Вывод картинок
|
||||
bool ReadImage(Aggplus::CImage* pImageRes, Object *pRef, Stream *pStream);
|
||||
virtual void drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override;
|
||||
virtual void setSoftMaskFromImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override;
|
||||
virtual void drawImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, int *pMaskColors, GBool bInlineImg, GBool interpolate) override;
|
||||
virtual void drawMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap,
|
||||
virtual void drawImageMask(GfxState *pGState, Gfx *gfx, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override;
|
||||
virtual void setSoftMaskFromImageMask(GfxState *pGState, Gfx *gfx, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override;
|
||||
virtual void drawImage(GfxState *pGState, Gfx *gfx, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, int *pMaskColors, GBool bInlineImg, GBool interpolate) override;
|
||||
virtual void drawMaskedImage(GfxState *pGState, Gfx *gfx, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap,
|
||||
Object* pMaskRef, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, GBool bMaskInvert, GBool interpolate) override;
|
||||
virtual void drawSoftMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap,
|
||||
virtual void drawSoftMaskedImage(GfxState *pGState, Gfx *gfx, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap,
|
||||
Object *maskRef, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, GfxImageColorMap *pMaskColorMap, double *pMatte, GBool interpolate) override;
|
||||
//----- Transparency groups и SMasks
|
||||
virtual void beginTransparencyGroup(GfxState *pGState, double *pBBox, GfxColorSpace *pBlendingColorSpace, GBool bIsolated, GBool bKnockout, GBool bForSoftMask) override;
|
||||
|
||||
Reference in New Issue
Block a user