mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-20 11:47:00 +08:00
develop new GetGlyphs
This commit is contained in:
@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user