develop new GetGlyphs

This commit is contained in:
Kulikova Svetlana
2021-10-20 18:09:29 +03:00
parent 533d04e8f3
commit b4701ac83c
3 changed files with 338 additions and 0 deletions

View File

@ -731,5 +731,219 @@ return 0;
oRes.ClearWithoutAttack();
return res;
}
BYTE* CPdfReader::GetGlyphs2(int nPageIndex)
{
if (!m_pInternal->m_pPDFDocument)
return NULL;
nPageIndex++;
TextOutputControl *pControl = new TextOutputControl();
pControl->mode = textOutPhysLayout;
NSWasm::CData oRes;
oRes.SkipLen();
TextOutputDev* pTextDev = new TextOutputDev(NULL, pControl, gFalse);
if (!pTextDev->isOk())
{
RELEASEOBJECT(pTextDev);
RELEASEOBJECT(pControl);
return NULL;
}
m_pInternal->m_pPDFDocument->displayPage(pTextDev, nPageIndex, 72.0, 72.0, 0, gFalse, gTrue, gTrue);
TextWordList* pWordList = pTextDev->makeWordList();
if (!pWordList)
{
RELEASEOBJECT(pTextDev);
RELEASEOBJECT(pControl);
return NULL;
}
CHLine m_oLine;
BYTE nLastColorR = 0, nLastColorG = 0, nLastColorB = 0;
for (int i = 0; i < pWordList->getLength(); i++)
{
TextWord* pWord = pWordList->get(i);
if (!pWord)
continue;
int amount = pWord->getLength();
for (int j = 0; j < amount; j++)
{
double _x1, _y1, _x2, _y2, r, g, b;
pWord->getCharBBox(j, &_x1, &_y1, &_x2, &_y2);
pWord->getColor(&r, &g, &b);
int nColorR = r, nColorG = g, nColorB = b;
TextFontInfo* pFontInfo = pWord->getFontInfo();
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 && (0 != nCountChars))
{
// не совпала baseline. поэтому просто скидываем линию в поток
DumpLine(m_oLine);
}
// теперь нужно определить сдвиг по baseline относительно destination точки
nCountChars = m_oLine.GetCountChars();
double dOffsetX = 0;
if (0 == nCountChars)
{
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;
// теперь посмотрим, может быть нужно вставить пробел??
CHChar* pLastChar = m_oLine.GetTail();
if (dOffsetX > (pLastChar->width + 0.5))
{
// вставляем пробел. Пробел у нас будет не совсем пробел. А специфический
CHChar* pSpaceChar = m_oLine.AddTail();
pSpaceChar->x = pLastChar->width;
pSpaceChar->width = dOffsetX - pLastChar->width;
pSpaceChar->unicode = 0xFFFF;
pSpaceChar->gid = 0xFFFF;
dOffsetX -= pLastChar->width;
oRes.WriteBYTE(0);
}
}
else
{
// буква сдвинута влево относительно предыдущей буквы
// на такую ситуацию реагируем просто - просто начинаем новую линию,
// предварительно сбросив старую
DumpLine(m_oLine);
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 bIsDumpFont = true;
bool bIsColor = nLastColorR != nColorR || nLastColorG != nColorG || nLastColorB != nColorB;
BYTE nLenMetaCommands = 0;
if (bIsColor)
nLenMetaCommands += 5;
if (bIsDumpFont)
nLenMetaCommands += 13;
oRes.WriteBYTE(nLenMetaCommands);
if (bIsDumpFont)
{
int lStyle = 0;
if (pFontInfo->isBold())
lStyle |= 0x01;
if (pFontInfo->isItalic())
lStyle |= 0x02;
oRes.WriteBYTE(41); // CMetafile::ctFontName
oRes.AddInt(0);
oRes.AddInt(lStyle);
oRes.WriteDouble(pWord->getFontSize());
}
if (bIsColor)
{
nLastColorR = nColorR;
nLastColorG = nColorG;
nLastColorB = nColorB;
oRes.WriteBYTE(22); // CMetafile::ctBrushColor1
oRes.WriteBYTE(nLastColorR);
oRes.WriteBYTE(nLastColorG);
oRes.WriteBYTE(nLastColorB);
oRes.WriteBYTE(255); // alpha
}
double dKoef = 0; // m_oFontManager.m_pFont->Size * 25.4 / (72 * m_oFontManager.m_oCurrentInfo.m_lUnitsPerEm);
double dKoefMetr = dAbsVec;
double dAscender = 0 * dKoef * dKoefMetr; // m_oFontManager.m_oCurrentInfo.m_lAscent * dKoef * dKoefMetr;
double dDescender = 0 * dKoef * dKoefMetr; // m_oFontManager.m_oCurrentInfo.m_lDescent * dKoef * dKoefMetr;
if (m_oLine.m_dAscent < dAscender)
m_oLine.m_dAscent = dAscender;
if (m_oLine.m_dDescent < dDescender)
m_oLine.m_dDescent = dDescender;
double dW = 1; // m_oFontManager.MeasureString((const unsigned int*)(input + lIndex), 1, 0, 0, dBoxX, dBoxY, dBoxW, dBoxH);
CHChar* pChar = m_oLine.AddTail();
pChar->unicode = pWord->getChar(j);
pChar->gid = j + 1;
pChar->x = dOffsetX;
pChar->width = dW * dAbsVec;
m_oLine.m_dEndX += dOffsetX * m_oLine.m_ex;
m_oLine.m_dEndY += dOffsetX * m_oLine.m_ey;
}
}
RELEASEOBJECT(pWordList);
oRes.WriteLen();
RELEASEOBJECT(pTextDev);
RELEASEOBJECT(pControl);
BYTE* res = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return res;
}
void CPdfReader::DumpLine(const CPdfReader::CHLine& m_oLine)
{
}
#endif
}