DjVu to clean

This commit is contained in:
Kulikova Svetlana
2021-12-24 10:08:50 +03:00
parent 67facf5e69
commit c0c11cf928
2 changed files with 0 additions and 436 deletions

View File

@ -484,427 +484,6 @@ BYTE* CDjVuFileImplementation::GetPageLinks (int nPageIndex)
catch (...) {}
return NULL;
}
void CDjVuFileImplementation::GetGlyphs(IRenderer* m_pRenderer, const std::wstring& bsUnicodeText, unsigned int* pGids, double x, double y)
{
// m_pInternal->GetUnicodes(bsUnicodeText);
int nLen = (int)bsUnicodeText.length();
int* pTempUnicodes = new int[nLen];
int nTempUnicodesLen = 0;
const wchar_t* pWchars = bsUnicodeText.c_str();
if (sizeof(wchar_t) == 2)
{
for (int i = 0; i < nLen; i++)
{
int code = (int)pWchars[i];
if (code >= 0xD800 && code <= 0xDFFF && (i + 1) < nLen)
code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & pWchars[++i]));
pTempUnicodes[nTempUnicodesLen++] = code;
}
}
else
for (int i = 0; i < nLen; i++)
pTempUnicodes[nTempUnicodesLen++] = (int)pWchars[i];
// m_pInternal->m_oWriter.WriteText(pTempUnicodes, (const int*)pGids, nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
bool bIsDumpFont = false;
std::wstring sCurrentFontName; double dFontSize;
m_pRenderer->get_FontName(&sCurrentFontName);
m_pRenderer->get_FontSize(&dFontSize);
int nCurrentFont = 0;
if ((nCurrentFont != m_lCurrentFont) || (dFontSize != m_dCurrentFontSize))
{
m_lCurrentFont = nCurrentFont;
m_dCurrentFontSize = dFontSize;
bIsDumpFont = true;
}
// m_oSmartText.CommandText(pTempUnicodes, (const int*)pGids, nTempUnicodesLen, x, y, w, h, bIsDumpFont, this);
// 1) сначала определяем точку отсчета и направление baseline
double _x1 = x;
double _y1 = y;
double _x2 = x + 1;
double _y2 = y;
double sx, shy, shx, sy, tx, ty, tmp;
m_pRenderer->GetTransform(&sx, &shy, &shx, &sy, &tx, &ty);
// m_pTransform->TransformPoint(_x1, _y1);
tmp = _x1;
_x1 = tmp * sx + _y1 * shx + tx;
_y1 = tmp * shy + _y1 * sy + ty;
// m_pTransform->TransformPoint(_x2, _y2);
tmp = _x2;
_x2 = tmp * sx + _y2 * shx + tx;
_y2 = tmp * shy + _y2 * sy + ty;
double _k = 0;
double _b = 0;
bool _isConstX = false;
if (fabs(_x1 - _x2) < 0.001)
{
_isConstX = true;
_b = _x1;
}
else
{
_k = (_y1 - _y2) / (_x1 - _x2);
_b = _y1 - _k * _x1;
}
double dAbsVec = sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2));
if (dAbsVec == 0)
dAbsVec = 1;
LONG nCountChars = m_oLine.GetCountChars();
bool bIsNewLine = true;
if (0 != nCountChars)
{
if (_isConstX && m_oLine.m_bIsConstX && fabs(_b - m_oLine.m_dB) < 0.001)
bIsNewLine = false;
else if (!_isConstX && !m_oLine.m_bIsConstX && fabs(_k - m_oLine.m_dK) < 0.001 && fabs(_b - m_oLine.m_dB) < 0.001)
bIsNewLine = false;
}
if (bIsNewLine && (nCountChars != 0))
{
// не совпала baseline. поэтому просто скидываем линию в поток
DumpLine();
}
// теперь нужно определить сдвиг по baseline относительно destination точки
nCountChars = m_oLine.GetCountChars();
double dOffsetX = 0;
if (nCountChars == 0)
{
m_oLine.m_bIsConstX = _isConstX;
m_oLine.m_dK = _k;
m_oLine.m_dB = _b;
m_oLine.m_dX = _x1;
m_oLine.m_dY = _y1;
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
m_oLine.m_dEndX = _x1;
m_oLine.m_dEndY = _y1;
}
else
{
double _sx = _x1 - m_oLine.m_dEndX;
double _sy = _y1 - m_oLine.m_dEndY;
double len = sqrt(_sx * _sx + _sy * _sy);
if (_sx * m_oLine.m_ex >= 0 && _sy * m_oLine.m_ey >= 0)
{
// продолжаем линию
dOffsetX = len;
// теперь посмотрим, может быть нужно вставить пробел??
NSWasm::CHChar* pLastChar = m_oLine.GetTail();
if (dOffsetX > (pLastChar->width + 0.5))
{
// вставляем пробел. Пробел у нас будет не совсем пробел. А специфический
NSWasm::CHChar* pSpaceChar = m_oLine.AddTail();
pSpaceChar->x = pLastChar->width;
pSpaceChar->width = dOffsetX - pLastChar->width;
pSpaceChar->unicode = 0xFFFF;
pSpaceChar->gid = 0xFFFF;
dOffsetX -= pLastChar->width;
m_oMeta.WriteBYTE(0);
}
}
else
{
// буква сдвинута влево относительно предыдущей буквы
// на такую ситуацию реагируем просто - просто начинаем новую линию,
// предварительно сбросив старую
DumpLine();
m_oLine.m_bIsConstX = _isConstX;
m_oLine.m_dX = _x1;
m_oLine.m_dY = _y1;
m_oLine.m_dK = _k;
m_oLine.m_dB = _b;
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
}
m_oLine.m_dEndX = _x1;
m_oLine.m_dEndY = _y1;
}
// смотрим, совпадает ли главная часть матрицы.
bool bIsTransform = !(fabs(m_pLastTransform.sx() - sx) < 0.001 &&
fabs(m_pLastTransform.sy() - sy) < 0.001 &&
fabs(m_pLastTransform.shx() - shx) < 0.001 &&
fabs(m_pLastTransform.shy() - shy) < 0.001);
if (bIsTransform)
bIsDumpFont = true;
LONG nColor1, nAlpha1;
m_pRenderer->get_BrushColor1(&nColor1);
m_pRenderer->get_BrushAlpha1(&nAlpha1);
bool bIsColor = ((nColor1 != m_nLastBrushColor1) || (nAlpha1 != m_nLastBrushAlpha1));
BYTE nLenMetaCommands = 0;
if (bIsColor)
nLenMetaCommands += 5;
if (bIsTransform)
nLenMetaCommands += 17;
if (bIsDumpFont)
nLenMetaCommands += 13;
m_oMeta.WriteBYTE(nLenMetaCommands);
double _dumpSize = dFontSize;
double _dumpMtx[4];
_dumpMtx[0] = sx;
_dumpMtx[1] = shy;
_dumpMtx[2] = shx;
_dumpMtx[3] = sy;
double dTextScale = std::min(sqrt(_dumpMtx[2] * _dumpMtx[2] + _dumpMtx[3] * _dumpMtx[3]),
sqrt(_dumpMtx[0] * _dumpMtx[0] + _dumpMtx[1] * _dumpMtx[1]));
if ((_dumpSize < 0.1 && dTextScale > 10) || (_dumpSize > 10 && dTextScale < 0.1))
{
_dumpSize *= dTextScale;
_dumpMtx[0] /= dTextScale;
_dumpMtx[1] /= dTextScale;
_dumpMtx[2] /= dTextScale;
_dumpMtx[3] /= dTextScale;
}
if (bIsDumpFont)
{
LONG nFontStyle;
m_pRenderer->get_FontStyle(&nFontStyle);
m_oMeta.WriteBYTE(41); // CMetafile::ctFontName
m_oMeta.AddInt(nCurrentFont);
m_oMeta.AddInt(nFontStyle);
m_oMeta.WriteDouble(_dumpSize);
}
if (bIsTransform)
{
m_pLastTransform.SetElements(sx, shy, shx, sy);
m_oLine.m_bIsSetUpTransform = true;
m_oLine.m_sx = sx;
m_oLine.m_shx = shx;
m_oLine.m_shy = shy;
m_oLine.m_sy = sy;
m_oMeta.WriteBYTE(161); // CMetafile::ctCommandTextTransform
m_oMeta.WriteDouble(_dumpMtx[0]);
m_oMeta.WriteDouble(_dumpMtx[1]);
m_oMeta.WriteDouble(_dumpMtx[2]);
m_oMeta.WriteDouble(_dumpMtx[3]);
}
if (bIsColor)
{
m_nLastBrushColor1 = nColor1;
m_nLastBrushAlpha1 = nAlpha1;
m_oMeta.WriteBYTE(22); // CMetafile::ctBrushColor1
LONG lBGR = nColor1;
m_oMeta.WriteBYTE((BYTE)(lBGR & 0xFF));
m_oMeta.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF));
m_oMeta.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF));
m_oMeta.WriteBYTE((BYTE)nAlpha1);
}
NSFonts::IFontManager *m_pFontManager = ((NSGraphics::IGraphicsRenderer*)m_pRenderer)->GetFontManager();
// все, baseline установлен. теперь просто продолжаем линию
if (bIsDumpFont)
{
m_pFontManager->LoadFontFromFile(sCurrentFontName, 0, dFontSize, 72.0, 72.0);
m_pFontManager->AfterLoad();
}
double dKoef = dFontSize * 25.4 / (72 * abs(m_pFontManager->GetUnitsPerEm()));
double dAscender = abs(m_pFontManager->GetAscender()) * dKoef * dAbsVec;
double dDescender = abs(m_pFontManager->GetDescender()) * dKoef * dAbsVec;
if (m_oLine.m_dAscent < dAscender)
m_oLine.m_dAscent = dAscender;
if (m_oLine.m_dDescent < dDescender)
m_oLine.m_dDescent = dDescender;
double dPlusOffset = 0;
int* input = NULL;
if (pGids)
{
input = (int*)pGids;
m_pFontManager->SetStringGID(TRUE);
}
else
{
input = pTempUnicodes;
m_pFontManager->SetStringGID(FALSE);
}
for (int i = 0; i < nTempUnicodesLen; i++)
{
// double dW = m_oFontManager.MeasureString((const unsigned int*)(input + lIndex), 1, 0, 0, dBoxX, dBoxY, dBoxW, dBoxH);
m_pFontManager->LoadString1((unsigned int*)(input + i), 1, 0, 0);
TBBox _box = m_pFontManager->MeasureString2();
double dBoxW = abs(_box.fMaxX - _box.fMinX) * 25.4 / 72.0;
NSWasm::CHChar* pChar = m_oLine.AddTail();
pChar->unicode = pTempUnicodes[i];
pChar->gid = pGids ? pGids[i] : 0xFFFF;
pChar->x = dOffsetX;
if (i != 0)
dPlusOffset += dOffsetX;
dOffsetX = dBoxW;
pChar->width = dBoxW * dAbsVec;
if (i != 0)
m_oMeta.WriteBYTE(0);
if (i == (nTempUnicodesLen - 1))
{
m_oLine.m_dEndX += dPlusOffset * m_oLine.m_ex;
m_oLine.m_dEndY += dPlusOffset * m_oLine.m_ey;
}
}
RELEASEARRAYOBJECTS(pTempUnicodes);
}
void CDjVuFileImplementation::DumpLine()
{
if (m_oLine.m_bIsSetUpTransform)
{
// выставится трансформ!!!
// cравнивать нужно с ним!!!
m_pLastTransform.SetElements(m_oLine.m_sx, m_oLine.m_shy, m_oLine.m_shx, m_oLine.m_sy);
}
// скидываем линию в поток pMeta
BYTE mask = 0;
if (fabs(m_oLine.m_ex - 1.0) < 0.001 && fabs(m_oLine.m_ey) < 0.001)
mask |= 0x01;
LONG lCountSpaces = 0;
LONG lCountSymbols = 0;
LONG lCountWords = 0;
bool bIsLastSymbol = false;
bool bIsGidExist = false;
LONG nCount = m_oLine.GetCountChars();
for (LONG i = 0; i < nCount; i++)
{
NSWasm::CHChar* pChar = &m_oLine.m_pChars[i];
if (pChar->gid != 0xFFFF)
{
mask |= 0x02;
bIsGidExist = true;
}
if (0xFFFF == pChar->unicode || L' ' == pChar->unicode || L'\t' == pChar->unicode)
{
lCountSpaces++;
if (bIsLastSymbol)
{
bIsLastSymbol = false;
lCountWords++;
}
}
else
{
bIsLastSymbol = true;
lCountSymbols++;
}
}
if (bIsLastSymbol)
lCountWords++;
if (0 == nCount)
{
m_oLine.Clear();
m_oMeta.ClearNoAttack();
return;
}
if (nCount > 1)
mask |= 0x04;
m_pPageMeta.WriteBYTE(160); // CMetafile::ctCommandTextLine
m_pPageMeta.WriteBYTE(mask);
m_pPageMeta.WriteDouble(m_oLine.m_dX);
m_pPageMeta.WriteDouble(m_oLine.m_dY);
if ((mask & 0x01) == 0)
{
m_pPageMeta.WriteDouble(m_oLine.m_ex);
m_pPageMeta.WriteDouble(m_oLine.m_ey);
}
m_pPageMeta.WriteDouble(m_oLine.m_dAscent);
m_pPageMeta.WriteDouble(m_oLine.m_dDescent);
LONG _position = 0;
if (nCount > 1)
{
_position = m_pPageMeta.GetSize();
m_pPageMeta.AddInt(0);
}
BYTE* pBufferMeta = m_oMeta.GetBuffer();
double dWidthLine = 0;
double dCurrentGlyphLineOffset = 0;
for (LONG lIndexChar = 0; lIndexChar < nCount; lIndexChar++)
{
NSWasm::CHChar* pChar = &m_oLine.m_pChars[lIndexChar];
// все настроки буквы (m_oMeta)
BYTE lLen = *pBufferMeta;
pBufferMeta++;
if (lLen > 0)
m_pPageMeta.Write(pBufferMeta, lLen);
pBufferMeta += lLen;
// смещение относительно предыдущей буквы (у всех, кроме первой)
// юникодное значение
// гид (если bIsGidExist == true)
// ширина буквы
m_pPageMeta.WriteBYTE(80); // CMetafile::ctDrawText
if (lIndexChar)
m_pPageMeta.WriteDouble2(pChar->x);
m_pPageMeta.WriteWCHAR(pChar->unicode);
if (bIsGidExist)
m_pPageMeta.WriteUSHORT(pChar->gid);
m_pPageMeta.WriteDouble2(pChar->width);
if (lIndexChar)
dCurrentGlyphLineOffset += pChar->x;
if (lIndexChar == (nCount - 1))
dWidthLine = dCurrentGlyphLineOffset + pChar->width;
}
if (nCount > 1)
{
int* pWidthBuf = (int*)(m_pPageMeta.GetBuffer() + _position);
*pWidthBuf = (int)(dWidthLine * 10000);
}
m_oLine.Clear();
m_oMeta.ClearNoAttack();
m_pPageMeta.WriteBYTE(162); // CMetafile::ctCommandTextLineEnd
}
#endif
void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPage, XmlUtils::CXmlNode& text)
{
@ -1573,9 +1152,6 @@ void CDjVuFileImplementation::DrawPageText(IRenderer* pRenderer, d
(float)(pdCoords[3]),
(float)(pdCoords[2] - pdCoords[0]),
(float)(pdCoords[1] - pdCoords[3]));
#ifdef BUILDING_WASM_MODULE
GetGlyphs(pRenderer, wsText, NULL, pdCoords[0], pdCoords[3]);
#endif
}
void CDjVuFileImplementation::ParseCoords(const std::wstring& wsCoordsStr, double* pdCoords, double dKoef)
{

View File

@ -86,18 +86,6 @@ public:
BYTE* GetStructure();
BYTE* GetPageGlyphs(int nPageIndex);
BYTE* GetPageLinks (int nPageIndex);
void GetGlyphs(IRenderer* pRenderer, const std::wstring& bsUnicodeText, unsigned int* pGids, double x, double y);
void DumpLine();
NSWasm::CData m_pPageMeta;
private:
double m_dCurrentFontSize = 0.0;
NSWasm::CHLine m_oLine;
NSWasm::CData m_oMeta;
Aggplus::CMatrix m_pLastTransform;
LONG m_lCurrentFont = -1;
LONG m_nLastBrushColor1 = -1;
LONG m_nLastBrushAlpha1 = -1;
#endif
private: