48 assert(ptr !=
nullptr);
49 sal_Int16
t = (ptr+offset)[0] << 8 | (ptr+offset)[1];
55 assert(ptr !=
nullptr);
56 sal_uInt16
t = (ptr+offset)[0] << 8 | (ptr+offset)[1];
62 assert(ptr !=
nullptr);
64 ptr[offset] =
static_cast<sal_uInt8>((val >> 8) & 0xFF);
65 ptr[offset+1] =
static_cast<sal_uInt8>(val & 0xFF);
70 assert(ptr !=
nullptr);
72 ptr[offset] =
static_cast<sal_uInt8>((val >> 8) & 0xFF);
73 ptr[offset+1] =
static_cast<sal_uInt8>(val & 0xFF);
78 assert(ptr !=
nullptr);
80 ptr[offset] =
static_cast<sal_uInt8>((val >> 24) & 0xFF);
81 ptr[offset+1] =
static_cast<sal_uInt8>((val >> 16) & 0xFF);
82 ptr[offset+2] =
static_cast<sal_uInt8>((val >> 8) & 0xFF);
83 ptr[offset+3] =
static_cast<sal_uInt8>(val & 0xFF);
88 sal_uInt32
const ltag(
static_cast<TableEntry const*
>(l)->tag);
89 sal_uInt32
const rtag(
static_cast<TableEntry const*
>(r)->tag);
90 return (ltag == rtag) ? 0 : (ltag < rtag) ? -1 : 1;
94struct NameRecordCompareF
96 bool operator()(
const NameRecord& l,
const NameRecord& r)
const
98 if (l.platformID != r.platformID) {
99 return l.platformID < r.platformID;
100 }
else if (l.encodingID != r.encodingID) {
101 return l.encodingID < r.encodingID;
102 }
else if (l.languageID != r.languageID) {
103 return l.languageID < r.languageID;
104 }
else if (l.nameID != r.nameID) {
105 return l.nameID < r.nameID;
112static sal_uInt32
CheckSum(sal_uInt32 *ptr, sal_uInt32 length)
115 sal_uInt32 *endptr = ptr + ((
length + 3) & sal_uInt32(~3)) / 4;
117 while (ptr < endptr) sum += *ptr++;
133 if (
table !=
nullptr) {
140 for (
auto it = this->
m_tables.begin(); it != this->m_tables.end(); )
142 if ((*it)->m_tag == tableTag)
153 sal_uInt16 searchRange=1, entrySelector=0, rangeShift;
154 sal_uInt32 s, offset, checkSumAdjustment = 0;
165 sal_uInt16 numTables = this->
m_tables.size();
167 std::unique_ptr<TableEntry[]> te(
new TableEntry[numTables]);
170 for (
auto const & e : this->
m_tables)
172 e->GetRawData(&te[teIdx]);
181 }
while (searchRange <= numTables);
185 rangeShift = numTables * 16 - searchRange;
187 s = offset = 12 + 16 * numTables;
189 for (
int i = 0;
i < numTables; ++
i) {
190 s += (te[
i].length + 3) & sal_uInt32(~3);
194 rOutBuffer.resize(s);
205 for (
int i = 0;
i < numTables; ++
i) {
215 memcpy(ttf+offset, te[
i].data, (te[
i].
length + 3) & sal_uInt32(~3) );
216 offset += (te[
i].length + 3) & sal_uInt32(~3);
222 p =
reinterpret_cast<sal_uInt32 *
>(ttf);
223 for (
int i = 0; i < static_cast<int>(s) / 4; ++
i) checkSumAdjustment +=
p[
i];
224 PutUInt32(0xB1B0AFBA - checkSumAdjustment, head, 8);
246#define CMAP_SUBTABLE_INIT 10
247#define CMAP_SUBTABLE_INCR 10
253 std::vector<std::pair<sal_uInt32, sal_uInt32>> mappings;
261 std::unique_ptr<CmapSubTable[]>
s;
266 std::unique_ptr<sal_uInt8[]>
ptr;
270static std::unique_ptr<sal_uInt8[]>
ttmalloc(sal_uInt32 nbytes)
272 sal_uInt32
n = (nbytes + 3) & sal_uInt32(~3);
273 return std::make_unique<sal_uInt8[]>(
n);
315 SAL_WARN(
"vcl.fonts",
"Unsupported format of a 'post' table: "
320 <<
static_cast<int>(
m_format) <<
".");
354 assert(this->
m_loca !=
nullptr);
376 sal_uInt32
n, nbytes = 0;
385 for (
const std::unique_ptr<GlyphData>& pGlyph :
m_list)
388 nbytes += pGlyph->nbytes;
394 for (
const std::unique_ptr<GlyphData>& pGlyph :
m_list)
398 memcpy(
p, pGlyph->ptr.get(),
n);
411static std::unique_ptr<sal_uInt8[]>
PackCmapType0(CmapSubTable
const *s, sal_uInt32 *length)
413 std::unique_ptr<sal_uInt8[]> ptr(
new sal_uInt8[262]);
420 for (sal_uInt32
i = 0;
i < 256;
i++) {
422 for (
const auto& [
ch, glyph] : s->mappings) {
424 g =
static_cast<sal_uInt16
>(glyph);
433static std::unique_ptr<sal_uInt8[]>
PackCmapType6(CmapSubTable
const *s, sal_uInt32 *length)
435 std::unique_ptr<sal_uInt8[]> ptr(
new sal_uInt8[s->mappings.size()*2 + 10]);
439 PutUInt16(
static_cast<sal_uInt16
>(s->mappings.size()*2+10), ptr.get(), 2);
442 PutUInt16(
static_cast<sal_uInt16
>(s->mappings.size()), ptr.get(), 8 );
444 for (
size_t i = 0;
i < s->mappings.size();
i++) {
446 for (
const auto& [
ch, glyph] : s->mappings) {
448 g =
static_cast<sal_uInt16
>(glyph);
453 *
length = s->mappings.size()*2+10;
458static std::unique_ptr<sal_uInt8[]>
PackCmap(CmapSubTable
const *s, sal_uInt32 *length)
460 if (s->mappings.back().second > 0xff)
478 std::unique_ptr<std::unique_ptr<sal_uInt8[]>[]> subtables(
new std::unique_ptr<
sal_uInt8[]>[
m_cmap->n]);
479 std::unique_ptr<sal_uInt32[]> sizes(
new sal_uInt32[
m_cmap->n]);
487 cmapsize = tlen + 4 + 8 *
m_cmap->n;
493 coffset = 4 +
m_cmap->n * 8;
499 memcpy(cmap + coffset, subtables[
i].
get(), sizes[
i]);
500 subtables[
i].reset();
526 std::vector<NameRecord> nr =
m_list;
529 stringLen += rName.sptr.size();
531 if (stringLen > 65535) {
535 std::sort(nr.begin(), nr.end(), NameRecordCompareF());
537 int nameLen = stringLen + 12 *
n + 6;
547 for (
i = 0;
i <
n;
i++) {
550 PutUInt16(
static_cast<sal_uInt16
>(nr[
i].languageID), p1, 4);
553 PutUInt16(
static_cast<sal_uInt16
>(p2 - (
name.get() + 6 + 12 *
n)), p1, 10);
554 if (nr[
i].sptr.size()) {
555 memcpy(p2, nr[
i].sptr.data(), nr[
i].sptr.size());
558 p2 += nr[
i].sptr.size();
566 te->
length =
static_cast<sal_uInt16
>(nameLen);
576 std::unique_ptr<sal_uInt8[]> post;
577 sal_uInt32 postLen = 0;
592 SAL_WARN(
"vcl.fonts",
"Unrecognized format of a post table: "
597 <<
static_cast<int>(
m_format) <<
".");
632 memcpy(
m_ptr.get(), ptr, nbytes);
643 m_ptr = std::move(ptr);
649 sal_uInt16 unitsPerEm,
652 sal_uInt16 lowestRecPPEM,
653 sal_Int16 fontDirectionHint)
657 assert(created !=
nullptr);
666 memcpy(ptr+20, created, 8);
667 memset(ptr+28, 0, 8);
677 sal_Int16 caretSlopeRise,
678 sal_Int16 caretSlopeRun)
703 this->
m_loca->ptr =
nullptr;
732 , m_list(
std::move(nr))
737 sal_Int32 italicAngle,
738 sal_Int16 underlinePosition,
739 sal_Int16 underlineThickness,
740 sal_uInt32 isFixedPitch)
743 assert(format == 0x00030000);
758 s =
m_cmap->s.get(); assert(s !=
nullptr);
772 for (sal_uInt32 j = 0; j !=
m_cmap->m; ++j) {
773 tmp[j] = std::move(s[j]);
777 m_cmap->s = std::move(tmp);
781 if (s[
i].
id >
id)
break;
785 for (sal_uInt32 j =
m_cmap->n; j !=
i; --j) {
786 s[j + 1] = std::move(s[j]);
795 s[
i].mappings.emplace_back(c, g);
800 sal_uInt32 currentID;
801 int ret,
n, ncomponents;
803 if (!glyphdata)
return sal_uInt32(~0);
805 std::vector< sal_uInt32 > glyphlist;
810 ret =
n =
m_list.back()->newID + 1;
814 glyphdata->newID =
n++;
815 m_list.push_back(std::move(glyphdata));
817 if (ncomponents > 1 && glyphlist.size() > 1 )
819 std::vector< sal_uInt32 >::const_iterator it = glyphlist.begin();
827 for (
const std::unique_ptr<GlyphData>& pGlyph :
m_list)
829 if (pGlyph->glyphID == currentID) {
838 m_list.push_back(std::move(gd));
840 }
while( ++it != glyphlist.end() );
848 for (
const std::unique_ptr<TrueTypeTable>&
p : this->
m_tables)
849 if (
p->m_tag == tableTag) {
876 std::unique_ptr<TrueTypeTableLoca> loca;
878 sal_uInt32 nGlyphs, locaLen = 0, glyfLen = 0;
879 sal_Int16 xMin = 0, yMin = 0, xMax = 0, yMax = 0;
881 sal_Int16 indexToLocFormat;
882 std::unique_ptr<sal_uInt8[]> hmtxPtr;
886 sal_uInt16 maxPoints = 0, maxContours = 0, maxCompositePoints = 0, maxCompositeContours = 0;
888 std::unique_ptr<sal_uInt32[]> gid;
891 std::vector<std::unique_ptr<GlyphData>>& glyphlist = glyf->
m_list;
892 nGlyphs = glyphlist.size();
895 SAL_WARN(
"vcl.fonts",
"no glyphs found in ProcessTables");
898 gid.reset(
new sal_uInt32[nGlyphs]);
905 for (
const std::unique_ptr<GlyphData>& gd : glyphlist)
907 glyfLen += gd->nbytes;
910 assert(gd->newID ==
i);
911 gid[
i++] = gd->glyphID;
916 if (gd->nbytes >= 10) {
917 sal_Int16
z =
GetInt16(gd->ptr.get(), 2);
918 if (
z < xMin) xMin =
z;
921 if (
z < yMin) yMin =
z;
924 if (
z > xMax) xMax =
z;
927 if (
z > yMax) yMax =
z;
931 if (gd->npoints > maxPoints) maxPoints = gd->npoints;
932 if (gd->ncontours > maxContours) maxContours = gd->ncontours;
934 if (gd->npoints > maxCompositePoints) maxCompositePoints = gd->npoints;
935 if (gd->ncontours > maxCompositeContours) maxCompositeContours = gd->ncontours;
940 indexToLocFormat = (glyfLen / 2 > 0xFFFF) ? 1 : 0;
941 locaLen = indexToLocFormat ? (nGlyphs + 1) << 2 : (nGlyphs + 1) << 1;
943 std::unique_ptr<sal_uInt8[]> glyfPtr =
ttmalloc(glyfLen);
944 std::unique_ptr<sal_uInt8[]> locaPtr =
ttmalloc(locaLen);
950 for (
const std::unique_ptr<GlyphData>& gd : glyphlist)
952 if (gd->compflag && gd->nbytes > 10) {
953 sal_uInt16 flags,
index;
955 size_t nRemaining = gd->nbytes - 10;
959 SAL_WARN(
"vcl.fonts",
"truncated font");
967 for (j = 0; j < nGlyphs; j++) {
968 if (gid[j] ==
index) {
974 PutUInt16(
static_cast<sal_uInt16
>(j), ptr, 2);
979 sal_uInt32 nAdvance = 0;
994 if (nRemaining < nAdvance)
996 SAL_WARN(
"vcl.fonts",
"truncated font");
1001 nRemaining -= nAdvance;
1006 if (gd->nbytes != 0) {
1007 memcpy(p1, gd->ptr.get(), gd->nbytes);
1009 if (indexToLocFormat == 1) {
1013 PutUInt16(
static_cast<sal_uInt16
>((p1 - glyfPtr.get()) >> 1), p2, 0);
1019 met[
i].adv = gd->aw;
1020 met[
i].sb = gd->lsb;
1026 if (indexToLocFormat == 1) {
1029 PutUInt16(
static_cast<sal_uInt16
>((p1 - glyfPtr.get()) >> 1), p2, 0);
1035 loca->m_loca->ptr = std::move(locaPtr);
1036 loca->m_loca->nbytes = locaLen;
1061 hheaPtr = hhea->
m_hhea.get();
1063 for (
i = nGlyphs - 1;
i > 0;
i--) {
1064 if (met[
i].adv != met[
i-1].adv)
break;
1066 nlsb = nGlyphs - 1 -
i;
1068 hmtxSize = (nGlyphs - nlsb) * 4 + nlsb * 2;
1072 for (
i = 0;
i < nGlyphs;
i++) {
1073 if (
i < nGlyphs - nlsb) {
1083 AddTable(std::make_unique<TrueTypeTableGeneric>(
T_hmtx, hmtxSize, std::move(hmtxPtr)));
1084 PutUInt16(
static_cast<sal_uInt16
>(nGlyphs - nlsb), hheaPtr, 34);
1098 return (a << 24) | (b << 16) | (c << 8) |
d;
1103 TrueTypeCreator *ttcr;
1106 TrueTypeCreatorNewEmpty(mkTag(
't',
'r',
'u',
'e'), &ttcr);
1108 t1 = malloc(1000); memset(t1,
'a', 1000);
1109 t2 = malloc(2000); memset(t2,
'b', 2000);
1110 t3 = malloc(3000); memset(t3,
'c', 3000);
1111 t4 = malloc(4000); memset(t4,
'd', 4000);
1112 t5 = malloc(5000); memset(t5,
'e', 5000);
1113 t6 = malloc(6000); memset(t6,
'f', 6000);
1115 AddTable(ttcr, TrueTypeTableNew(
T_maxp, 1000, t1));
1116 AddTable(ttcr, TrueTypeTableNew(
T_OS2, 2000, t2));
1117 AddTable(ttcr, TrueTypeTableNew(
T_cmap, 3000, t3));
1118 AddTable(ttcr, TrueTypeTableNew(
T_loca, 4000, t4));
1119 AddTable(ttcr, TrueTypeTableNew(
T_hhea, 5000, t5));
1120 AddTable(ttcr, TrueTypeTableNew(
T_glyf, 6000, t6));
1129 StreamToFile(ttcr,
"ttcrout.ttf");
1131 TrueTypeCreatorDispose(ttcr);
sal_uInt32 m_tag
TrueType file tag.
TrueTypeTable * FindTable(sal_uInt32 tag)
TrueTypeCreator(sal_uInt32 tag)
TrueTypeCreator constructor.
void RemoveTable(sal_uInt32 tag)
Removes a TrueType table from the TrueType creator if it is stored there.
~TrueTypeCreator()
TrueTypeCreator destructor.
SFErrCodes StreamToMemory(std::vector< sal_uInt8 > &rOutBuffer)
Writes a TrueType font generated by the TrueTypeCreator to a segment of memory that this method alloc...
void AddTable(std::unique_ptr< TrueTypeTable > table)
Adds a TrueType table to the TrueType creator.
std::vector< std::unique_ptr< TrueTypeTable > > m_tables
List of table tags and pointers.
void cmapAdd(sal_uInt32 id, sal_uInt32 c, sal_uInt32 g)
Add a character/glyph pair to a cmap table.
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
virtual ~TrueTypeTableCmap() override
std::unique_ptr< table_cmap > m_cmap
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
std::unique_ptr< sal_uInt8[]> m_ptr
TrueTypeTableGeneric(sal_uInt32 tag, sal_uInt32 nbytes, const sal_uInt8 *ptr)
Creates a new raw TrueType table.
virtual ~TrueTypeTableGeneric() override
Creates a new empty 'glyf' table.
sal_uInt32 glyfAdd(std::unique_ptr< GlyphData > glyphdata, AbstractTrueTypeFont *fnt)
Add a glyph to a glyf table.
std::vector< std::unique_ptr< GlyphData > > m_list
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
virtual ~TrueTypeTableGlyf() override
Creates a new 'head' table for a TrueType font.
std::unique_ptr< sal_uInt8[]> m_head
TrueTypeTableHead(sal_uInt32 fontRevision, sal_uInt16 flags, sal_uInt16 unitsPerEm, const sal_uInt8 *created, sal_uInt16 macStyle, sal_uInt16 lowestRecPPEM, sal_Int16 fontDirectionHint)
virtual ~TrueTypeTableHead() override
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
Creates a new 'hhea' table for a TrueType font.
TrueTypeTableHhea(sal_Int16 ascender, sal_Int16 descender, sal_Int16 linegap, sal_Int16 caretSlopeRise, sal_Int16 caretSlopeRun)
virtual ~TrueTypeTableHhea() override
std::unique_ptr< sal_uInt8[]> m_hhea
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
Creates a new empty 'loca' table for a TrueType font.
virtual ~TrueTypeTableLoca() override
std::unique_ptr< tdata_loca > m_loca
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
Creates a new 'maxp' table based on an existing maxp table.
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
virtual ~TrueTypeTableMaxp() override
TrueTypeTableMaxp(const sal_uInt8 *maxp, int size)
std::unique_ptr< sal_uInt8[]> m_maxp
TrueTypeTableName(std::vector< NameRecord > nr)
virtual ~TrueTypeTableName() override
std::vector< NameRecord > m_list
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
sal_Int16 m_underlineThickness
virtual int GetRawData(TableEntry *) override
This function converts the data of a TrueType table to a raw array of bytes.
TrueTypeTablePost(sal_Int32 format, sal_Int32 italicAngle, sal_Int16 underlinePosition, sal_Int16 underlineThickness, sal_uInt32 isFixedPitch)
sal_uInt32 m_isFixedPitch
virtual ~TrueTypeTablePost() override
sal_Int16 m_underlinePosition
std::unique_ptr< sal_uInt8[]> m_rawdata
int GetTTGlyphComponents(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vector< sal_uInt32 > &glyphlist)
For a specified glyph adds all component glyphs IDs to the list and return their number.
std::unique_ptr< GlyphData > GetTTRawGlyphData(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID)
Extracts raw glyph data from the 'glyf' table and returns it in an allocated GlyphData structure.
#define SAL_WARN(area, stream)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
constexpr sal_uInt32 T_post
constexpr sal_uInt32 T_loca
static std::unique_ptr< sal_uInt8[]> PackCmap(CmapSubTable const *s, sal_uInt32 *length)
constexpr int HHEA_Length
constexpr int HEAD_yMax_offset
SFErrCodes
Return value of OpenTTFont() and CreateT3FromTTGlyphs()
@ TtFormat
incorrect TrueType font format
constexpr int MAXP_maxCompositePoints_offset
constexpr sal_uInt32 T_glyf
static void PutUInt32(sal_uInt32 val, sal_uInt8 *ptr, sal_uInt32 offset)
constexpr int MAXP_Version1Length
static void PutInt16(sal_Int16 val, sal_uInt8 *ptr, sal_uInt32 offset)
static std::unique_ptr< sal_uInt8[]> PackCmapType0(CmapSubTable const *s, sal_uInt32 *length)
constexpr sal_uInt32 T_hhea
constexpr int MAXP_maxCompositeContours_offset
static int TableEntryCompareF(const void *l, const void *r)
static void PutUInt16(sal_uInt16 val, sal_uInt8 *ptr, sal_uInt32 offset)
constexpr int MAXP_maxPoints_offset
static sal_uInt32 CheckSum(sal_uInt32 *ptr, sal_uInt32 length)
@ TTCR_POSTFORMAT
unsupported format of a 'post' table
@ TTCR_ZEROGLYPHS
At least one glyph should be defined
@ TTCR_NONAMES
'name' table does not contain any names
@ TTCR_NAMETOOLONG
'name' table is too long (string data > 64K)
constexpr int HEAD_xMax_offset
constexpr sal_uInt32 T_head
static sal_Int16 GetInt16(const sal_uInt8 *ptr, size_t offset)
constexpr int HEAD_yMin_offset
constexpr int MAXP_maxContours_offset
constexpr int HEAD_xMin_offset
constexpr int MAXP_numGlyphs_offset
static std::unique_ptr< sal_uInt8[]> ttmalloc(sal_uInt32 nbytes)
static std::unique_ptr< sal_uInt8[]> PackCmapType6(CmapSubTable const *s, sal_uInt32 *length)
constexpr sal_uInt32 T_maxp
constexpr sal_uInt32 T_OS2
constexpr int HEAD_indexToLocFormat_offset
constexpr sal_uInt32 T_hmtx
constexpr sal_uInt32 T_name
static sal_uInt16 GetUInt16(const sal_uInt8 *ptr, size_t offset)
constexpr int HEAD_Length
constexpr sal_uInt32 T_cmap
@ WE_HAVE_AN_X_AND_Y_SCALE
Structure used by the TrueType Creator and CreateTTFromTTGlyphs()
Structure used by GetTTSimpleCharMetrics() functions.
std::unique_ptr< CmapSubTable[]> s
std::unique_ptr< sal_uInt8[]> ptr
#define CMAP_SUBTABLE_INIT
#define CMAP_SUBTABLE_INCR