/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*/
#include <string.h>
#include <vector>
#include <tools/vcompat.hxx>
#include <cstdio>
#include <tools/stream.hxx>
#include <vcl/font/EOTConverter.hxx>
#include <osl/endian.h>
#include <font/TTFStructure.hxx>
#include <font/TTFReader.hxx>
namespace font
{
namespace
{
// Writes padding, length and string data to font output
void writeNameTableString(font::TTFFont& rFont,
std::unique_ptr<NameTableHandler>& pNameTableHandler,
font::NameID eNameID, std::vector<sal_uInt8>& rEotOutput)
{
sal_uInt64 nOffset = 0 ;
sal_uInt16 nLength = 0 ;
// Padding
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
if (pNameTableHandler
&& pNameTableHandler->findEnglishUnicodeNameOffset(eNameID, nOffset, nLength))
{
// Length
rEotOutput.push_back(sal_uInt8((nLength + 2 ) & 0 xff));
rEotOutput.push_back(sal_uInt8((nLength + 2 ) >> 8 ));
OUString aString = rFont.getNameTableString(nOffset, nLength);
for (sal_Int32 i = 0 ; i < aString.getLength(); i++)
{
sal_Unicode nUniChar = aString[i];
rEotOutput.push_back(sal_uInt8(nUniChar & 0 xff));
rEotOutput.push_back(sal_uInt8(nUniChar >> 8 ));
}
// null terminated
rEotOutput.push_back(sal_uInt8(0 ));
rEotOutput.push_back(sal_uInt8(0 ));
}
else
{
// Length 0
rEotOutput.push_back(sal_uInt8(0 ));
rEotOutput.push_back(sal_uInt8(0 ));
}
}
}
bool EOTConverter::convert(std::vector<sal_uInt8>& rEotOutput)
{
font::TTFFont aFont(mrFontDataContainer);
rEotOutput.clear();
rEotOutput.resize(sizeof (EOTHeader));
EOTHeader* pEot = reinterpret_cast <EOTHeader*>(rEotOutput.data());
pEot->nFontDataSize = mrFontDataContainer.size();
pEot->nVersion = 0 x00020002;
pEot->nFlags = 0 ;
pEot->nCharset = 0 ;
pEot->nMagicNumber = 0 x504c;
pEot->nReserved1 = 0 ;
pEot->nReserved2 = 0 ;
pEot->nReserved3 = 0 ;
pEot->nReserved4 = 0 ;
auto pHandler = aFont.getTableEntriesHandler();
if (!pHandler)
return false ;
const font::OS2Table* pOS2 = pHandler->getOS2Table();
if (pOS2)
{
for (sal_uInt32 n = 0 ; n < 10 ; n++)
pEot->nFontPANOSE[n] = pOS2->nPanose[n];
pEot->nItalic = pOS2->nFsSelection & 0 x01;
pEot->nWeight = pOS2->nWeightClass;
// FIXME: Should use OS2->fsType, but some TrueType fonts set it to an over-restrictive value.
// Since ATS does not enforce this on Mac OS X, we do not enforce it either.
pEot->nFsType = 0 x0000;
pEot->nUnicodeRange1 = pOS2->nUnicodeRange1;
pEot->nUnicodeRange2 = pOS2->nUnicodeRange2;
pEot->nUnicodeRange3 = pOS2->nUnicodeRange3;
pEot->nUnicodeRange4 = pOS2->nUnicodeRange4;
pEot->nCodePageRange1 = pOS2->nCodePageRange1;
pEot->nCodePageRange2 = pOS2->nCodePageRange2;
}
const font::HeadTable* pHeadTable = pHandler->getHeadTable();
if (pHeadTable)
{
pEot->nCheckSumAdjustment = pHeadTable->nCheckSumAdjustment;
}
auto pNameTableHandler = pHandler->getNameTableHandler();
writeNameTableString(aFont, pNameTableHandler, font::NameID::FamilyName, rEotOutput);
writeNameTableString(aFont, pNameTableHandler, font::NameID::SubfamilyName, rEotOutput);
writeNameTableString(aFont, pNameTableHandler, font::NameID::Version, rEotOutput);
writeNameTableString(aFont, pNameTableHandler, font::NameID::FullFontName, rEotOutput);
// Padding5
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
// Root String Size
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
// Root String CheckSum (for size 0)
rEotOutput.push_back(0 x42);
rEotOutput.push_back(0 x53);
rEotOutput.push_back(0 x47);
rEotOutput.push_back(0 x50);
// EUDC CodePage
rEotOutput.push_back(0 xE4);
rEotOutput.push_back(0 x04);
rEotOutput.push_back(0 x00);
rEotOutput.push_back(0 x00);
// Padding6
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
// Signature Size = should be 0x0000
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
// EUDC Flags
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
// EUDC Font Size = 0
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
rEotOutput.push_back(0 );
// rEOTOutput could've been reallocated - need to reinterpret that.
pEot = reinterpret_cast <EOTHeader*>(rEotOutput.data());
pEot->nEotSize = rEotOutput.size() + mrFontDataContainer.size();
rEotOutput.insert(rEotOutput.end(), mrFontDataContainer.begin(), mrFontDataContainer.end());
return true ;
}
} // end font namespace
int TestEOT(const void * data, sal_uInt32 size)
{
const sal_uInt8* bytes = static_cast <const sal_uInt8*>(data);
std::vector<sal_uInt8> input(bytes, bytes + size);
std::vector<sal_uInt8> aEOT;
font::FontDataContainer aContainer(input);
font::EOTConverter aConverter(aContainer);
return aConverter.convert(aEOT) ? 1 : 0 ;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=93 H=94 G=93
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland