39#ifdef SYSTEM_LIBFIXMATH
40#include <libfixmath/fix16.hpp>
47#include <rtl/ustring.hxx>
48#include <rtl/ustrbuf.hxx>
51#include <osl/endian.h>
52#include <osl/thread.h>
63const char *
const modname =
"SunTypeTools-TT";
86 explicit PSPathElement( PathSegmentType i_eType ) :
type( i_eType ),
93 PSPathElement() :
type( PS_NOOP ),
103struct TTGlyphMetrics {
113constexpr int HFORMAT_LINELEN = 64;
125 void BlockWrite(
const void *ptr, sal_uInt32
size);
129 char buffer[HFORMAT_LINELEN];
136 GlyphOffsets(
sal_uInt8 *sfntP, sal_uInt32 sfntLen);
138 std::unique_ptr<sal_uInt32[]> offs;
147 assert(ptr !=
nullptr);
149 t = (ptr+offset)[0] << 8 | (ptr+offset)[1];
157 assert(ptr !=
nullptr);
159 t = (ptr+offset)[0] << 8 | (ptr+offset)[1];
167 assert(ptr !=
nullptr);
169 t = (ptr+offset)[0] << 24 | (ptr+offset)[1] << 16 |
170 (ptr+offset)[2] << 8 | (ptr+offset)[3];
178 assert(ptr !=
nullptr);
180 t = (ptr+offset)[0] << 24 | (ptr+offset)[1] << 16 |
181 (ptr+offset)[2] << 8 | (ptr+offset)[3];
207 return (
n * 1000) / unitsPerEm;
213 static const char HexChars[] =
"0123456789ABCDEF";
222 size_t nWritten = o->WriteBytes(buffer, bufpos);
223 bRet = nWritten == bufpos;
229void HexFmt::OpenString()
231 o->WriteOString(
"<\n");
234void HexFmt::CloseString()
237 o->WriteOString(
"00\n>\n");
240void HexFmt::BlockWrite(
const void *ptr, sal_uInt32 size)
242 if (total + size > 65534) {
249 for (sal_uInt32 i = 0;
i <
size; ++
i) {
251 buffer[bufpos++] =
toHex(Ch >> 4);
252 buffer[bufpos++] =
toHex(Ch & 0xF);
253 if (bufpos == HFORMAT_LINELEN) {
255 o->WriteOString(
"\n");
270 metrics->aw = metrics->lsb = metrics->ah = 0;
274 if (glyphID < ttf->horzMetricCount())
289 if (glyphID < ttf->vertMetricCount())
295static int GetTTGlyphOutline(AbstractTrueTypeFont *, sal_uInt32 , std::vector<ControlPoint>&, TTGlyphMetrics *, std::vector< sal_uInt32 >* );
299 std::vector<ControlPoint>& pointArray, TTGlyphMetrics *metrics)
301 sal_uInt32 nTableSize;
311 sal_uInt32 nGlyphOffset = ttf->
glyphOffset(glyphID);
312 if (nGlyphOffset > nTableSize)
316 const sal_uInt32 nMaxGlyphSize = nTableSize - nGlyphOffset;
317 constexpr sal_uInt32 nContourOffset = 10;
318 if (nMaxGlyphSize < nContourOffset)
322 if( numberOfContours <= 0 )
325 const sal_Int32 nMaxContours = (nMaxGlyphSize - nContourOffset)/2;
326 if (numberOfContours > nMaxContours)
338 sal_uInt16 lastPoint=0;
339 for (
i=0;
i<numberOfContours;
i++)
341 const sal_uInt16
t =
GetUInt16(ptr, nContourOffset +
i * 2);
346 sal_uInt32 nInstLenOffset = nContourOffset + numberOfContours * 2;
347 if (nInstLenOffset + 2 > nMaxGlyphSize)
349 sal_uInt16 instLen =
GetUInt16(ptr, nInstLenOffset);
351 sal_uInt32 nOffset = nContourOffset + 2 * numberOfContours + 2 + instLen;
352 if (nOffset > nMaxGlyphSize)
356 sal_uInt32 nBytesRemaining = nMaxGlyphSize - nOffset;
357 const sal_uInt32 palen = lastPoint+1;
360 if (palen > nBytesRemaining || lastPoint > nBytesRemaining-1)
362 SAL_WARN(
"vcl.fonts",
"Font " << OUString::createFromAscii(ttf->
fileName()) <<
363 "claimed a palen of "
364 << palen <<
" but max bytes remaining is " << nBytesRemaining);
368 std::vector<ControlPoint> pa(palen);
371 while (
i <= lastPoint) {
372 if (!nBytesRemaining)
374 SAL_WARN(
"vcl.fonts",
"short read");
379 pa[
i++].flags =
static_cast<sal_uInt32
>(flag);
381 if (!nBytesRemaining)
383 SAL_WARN(
"vcl.fonts",
"short read");
389 for (j=0; j<
n; j++) {
393 pa[
i++].flags = flag;
400 for (
i = 0;
i <= lastPoint;
i++) {
401 if (pa[
i].flags & 0x02) {
402 if (!nBytesRemaining)
404 SAL_WARN(
"vcl.fonts",
"short read");
407 if (pa[
i].flags & 0x10) {
408 z +=
static_cast<int>(*
p++);
410 z -=
static_cast<int>(*
p++);
413 }
else if ( !(pa[
i].flags & 0x10)) {
414 if (nBytesRemaining < 2)
416 SAL_WARN(
"vcl.fonts",
"short read");
421 nBytesRemaining -= 2;
423 pa[
i].x =
static_cast<sal_Int16
>(
z);
428 for (
i = 0;
i <= lastPoint;
i++) {
429 if (pa[
i].flags & 0x04) {
430 if (!nBytesRemaining)
432 SAL_WARN(
"vcl.fonts",
"short read");
435 if (pa[
i].flags & 0x20) {
441 }
else if ( !(pa[
i].flags & 0x20)) {
442 if (nBytesRemaining < 2)
444 SAL_WARN(
"vcl.fonts",
"short read");
449 nBytesRemaining -= 2;
451 pa[
i].y =
static_cast<sal_Int16
>(
z);
454 for (
i=0;
i<numberOfContours;
i++) {
455 sal_uInt16 offset =
GetUInt16(ptr, 10 +
i * 2);
456 SAL_WARN_IF(offset >= palen,
"vcl.fonts",
"Font " << OUString::createFromAscii(ttf->
fileName()) <<
457 " contour " <<
i <<
" claimed an illegal offset of "
458 << offset <<
" but max offset is " << palen-1);
461 pa[offset].flags |= 0x00008000;
464 pointArray = std::move(pa);
465 return lastPoint + 1;
471 return sal_uInt32(
n) << 2;
475 TTGlyphMetrics *metrics, std::vector<sal_uInt32>& glyphlist)
477 sal_uInt16 flags,
index;
479 sal_uInt32 nTableSize;
481 std::vector<ControlPoint> myPoints;
482 std::vector<ControlPoint> nextComponent;
484 F16Dot16 a = 0x10000, b = 0, c = 0,
d = 0x10000,
m,
n, abs1, abs2, abs3;
491 sal_uInt32 nGlyphOffset = ttf->
glyphOffset(glyphID);
492 if (nGlyphOffset > nTableSize)
496 sal_uInt32 nAvailableBytes = nTableSize - nGlyphOffset;
512 if (nAvailableBytes < 10)
514 SAL_WARN(
"vcl.fonts",
"short read");
519 nAvailableBytes -= 10;
523 if (nAvailableBytes < 4)
525 SAL_WARN(
"vcl.fonts",
"short read");
532 nAvailableBytes -= 4;
534 if( std::find( glyphlist.begin(), glyphlist.end(),
index ) != glyphlist.end() )
536 SAL_WARN(
"vcl.fonts",
"Endless loop found in a compound glyph.");
538#if OSL_DEBUG_LEVEL > 1
539 std::ostringstream oss;
540 oss <<
index <<
" -> [";
541 for(
const auto& rGlyph : glyphlist )
543 oss << (
int) rGlyph <<
" ";
552 glyphlist.push_back(
index );
556 if( ! glyphlist.empty() )
557 glyphlist.pop_back();
562 SAL_WARN(
"vcl.fonts",
"An empty compound!");
571 if (nAvailableBytes < 4)
573 SAL_WARN(
"vcl.fonts",
"short read");
580 nAvailableBytes -= 4;
582 if (nAvailableBytes < 2)
584 SAL_WARN(
"vcl.fonts",
"short read");
596 nAvailableBytes -= 2;
603 if (nAvailableBytes < 2)
605 SAL_WARN(
"vcl.fonts",
"short read");
611 nAvailableBytes -= 2;
613 if (nAvailableBytes < 4)
615 SAL_WARN(
"vcl.fonts",
"short read");
621 nAvailableBytes -= 4;
623 if (nAvailableBytes < 8)
625 SAL_WARN(
"vcl.fonts",
"short read");
633 nAvailableBytes -= 8;
636 abs1 = (
a < 0) ? -
a :
a;
637 abs2 = (b < 0) ? -b : b;
638 m = std::max(abs1, abs2);
640 if (abs3 < 0) abs3 = -abs3;
641 if (abs3 <= 33)
m *= 2;
643 abs1 = (c < 0) ? -c : c;
644 abs2 = (
d < 0) ? -
d :
d;
645 n = std::max(abs1, abs2);
647 if (abs3 < 0) abs3 = -abs3;
648 if (abs3 <= 33)
n *= 2;
650 SAL_WARN_IF(np && (!
m || !
n),
"vcl.fonts",
"Parsing error in " << OUString::createFromAscii(ttf->
fileName()) <<
653 if (
m != 0 &&
n != 0) {
654 for (
i=0;
i<np;
i++) {
657 cp.
flags = nextComponent[
i].flags;
658 const sal_uInt16
x = nextComponent[
i].x;
659 const sal_uInt16
y = nextComponent[
i].y;
661 cp.
x =
static_cast<sal_Int16
>(
fixedMul(
t,
m) >> 16);
663 cp.
y =
static_cast<sal_Int16
>(
fixedMul(
t,
n) >> 16);
665 myPoints.push_back( cp );
670 SAL_WARN(
"vcl.fonts",
"number of points has to be limited to max value GlyphData::npoints can contain, abandon effort");
679 if( myPoints.empty() )
682 np = myPoints.size();
684 pointArray = std::move(myPoints);
698 sal_uInt32 glyflength;
700 sal_Int16 numberOfContours;
705 memset(metrics, 0,
sizeof(TTGlyphMetrics));
710 sal_uInt32 nNextOffset = ttf->
glyphOffset(glyphID + 1);
711 if (nNextOffset > glyflength)
715 if (nOffset > nNextOffset)
718 int length = nNextOffset - nOffset;
720 if (metrics)
GetMetrics(ttf, glyphID, metrics);
725 const sal_uInt32 nMaxGlyphSize = glyflength - nOffset;
727 if (nMaxGlyphSize < 2)
730 numberOfContours =
GetInt16(ptr, 0);
732 if (numberOfContours >= 0)
738 std::vector< sal_uInt32 > aPrivList { glyphID };
739 res =
GetCompoundTTOutline(ttf, glyphID, pointArray, metrics, glyphlist ? *glyphlist : aPrivList );
749 std::vector< PSPathElement > aPathList;
751 PSPathElement
p( PS_NOOP );
753 int x0 = 0, y0 = 0, x1 = 0, y1 = 0, x2, y2, curx, cury;
754 bool lastOff =
false;
758 int StartContour = 0, EndContour = 1;
763 while (srcCount > 0) {
767 while (!(srcA[l].flags & 0x8000)) l++;
769 if (StartContour == EndContour) {
770 if (cp + 1 < srcCount) {
777 p = PSPathElement(PS_MOVETO);
778 if (!(srcA[cp].flags & 1)) {
779 if (!(srcA[EndContour].flags & 1)) {
780 p.x1 = x0 = (srcA[cp].
x + srcA[EndContour].
x + 1) / 2;
781 p.y1 = y0 = (srcA[cp].
y + srcA[EndContour].
y + 1) / 2;
783 p.x1 = x0 = srcA[EndContour].
x;
784 p.y1 = y0 = srcA[EndContour].
y;
787 p.x1 = x0 = srcA[cp].
x;
788 p.y1 = y0 = srcA[cp].
y;
791 aPathList.push_back(
p );
799 if (srcA[cp].flags & 1)
803 p = PSPathElement(PS_CURVETO);
804 p.x1 = x0 + (2 * (x1 - x0) + 1) / 3;
805 p.y1 = y0 + (2 * (y1 - y0) + 1) / 3;
806 p.x2 = x1 + (curx - x1 + 1) / 3;
807 p.y2 = y1 + (cury - y1 + 1) / 3;
810 aPathList.push_back(
p );
814 if (x0 != curx || y0 != cury)
816 p = PSPathElement(PS_LINETO);
819 aPathList.push_back(
p );
822 x0 = curx; y0 = cury; lastOff =
false;
828 x2 = (x1 + curx + 1) / 2;
829 y2 = (y1 + cury + 1) / 2;
830 p = PSPathElement(PS_CURVETO);
831 p.x1 = x0 + (2 * (x1 - x0) + 1) / 3;
832 p.y1 = y0 + (2 * (y1 - y0) + 1) / 3;
833 p.x2 = x1 + (x2 - x1 + 1) / 3;
834 p.y2 = y1 + (y2 - y1 + 1) / 3;
837 aPathList.push_back(
p );
839 x1 = curx; y1 = cury;
841 x1 = curx; y1 = cury;
847 aPathList.emplace_back(PS_CLOSEPATH );
851 if (cp >= srcCount)
break;
855 if (cp == EndContour) {
863 if( (nPathCount =
static_cast<int>(aPathList.size())) > 0)
865 path.reset(
new PSPathElement[nPathCount]);
866 memcpy( path.get(), aPathList.data(), nPathCount *
sizeof(PSPathElement) );
882 const int available_space = ptr > end_table ? 0 : (end_table - ptr);
883 if( (len <= 0) || len > available_space)
893 res.setLength(len/2);
894 for (
int i = 0;
i < len/2;
i++)
896 res[
i] = *(ptr +
i * 2 + 1);
897 SAL_WARN_IF(res[
i] == 0,
"vcl.fonts",
"font name is bogus");
901 OUStringBuffer buf(len/2);
902 buf.setLength(len/2);
903 for (
int i = 0;
i < len/2;
i++ )
906 SAL_WARN_IF(buf[
i] == 0,
"vcl.fonts",
"font name is bogus");
908 *ucs2result = buf.makeStringAndClear();
912 memcpy(
static_cast<void*
>(
const_cast<char*
>(res.getStr())), ptr, len);
915 return res.makeStringAndClear();
919 sal_uInt16 encodingID, sal_uInt16 languageID, sal_uInt16 nameID )
921 if (
n == 0)
return -1;
927 m1 = (platformID << 16) | encodingID;
928 m2 = (languageID << 16) | nameID;
931 const int i = (l + r) >> 1;
935 if (! ((m1 < t1) || ((m1 == t1) && (m2 < t2)))) l =
i + 1;
936 if (! ((m1 > t1) || ((m1 == t1) && (m2 > t2)))) r =
i - 1;
961 sal_uInt32 nTableSize;
966#if OSL_DEBUG_LEVEL > 1
967 SAL_WARN(
"vcl.fonts",
"O_name table too small.");
975 const size_t nMinRecordSize = 12;
976 const size_t nSpaceAvailable = nTableSize - 6;
977 const size_t nMaxRecords = nSpaceAvailable/nMinRecordSize;
978 if (
n >= nMaxRecords)
982 bool bPSNameOK =
true;
988 if (
t->psname.isEmpty() && (r =
findname(
table,
n, 1, 0, 0, 6)) != -1)
990 if (
t->psname.isEmpty() && (r =
findname(
table,
n, 3, 0, 0x0409, 6)) != -1)
996 if (
t->psname.isEmpty() && (r =
findname(
table,
n, 2, 2, 0, 6)) != -1)
1000 if (
t->psname.isEmpty() )
1002 if (!
t->fileName().empty())
1004 const char* pReverse =
t->fileName().data() +
t->fileName().length();
1006 while (pReverse !=
t->fileName().data() && *pReverse !=
'/') pReverse--;
1007 if(*pReverse ==
'/') pReverse++;
1008 int nReverseLen = strlen(pReverse);
1009 for (
i=nReverseLen - 1;
i > 0;
i--)
1012 if (*(pReverse +
i) ==
'.' ) {
1017 t->psname = OString(std::string_view(pReverse, nReverseLen));
1020 t->psname =
"Unknown";
1027 if (
t->family.isEmpty() && (r =
findname(
table,
n, 3, 1, 0x0409, 1)) != -1)
1029 if (
t->family.isEmpty() && (r =
findname(
table,
n, 1, 0, 0, 1)) != -1)
1031 if (
t->family.isEmpty() && (r =
findname(
table,
n, 3, 1, 0x0411, 1)) != -1)
1033 if (
t->family.isEmpty() && (r =
findname(
table,
n, 3, 0, 0x0409, 1)) != -1)
1035 if (
t->family.isEmpty() )
1036 t->family =
t->psname;
1038 t->subfamily.clear();
1039 t->usubfamily.clear();
1042 if (
t->subfamily.isEmpty() && (r =
findname(
table,
n, 3, 1, 0x0409, 2)) != -1)
1051 for(
i = 0;
i <
t->psname.getLength() && bPSNameOK;
i++ )
1052 if(
t->psname[
i ] < 33 || (
t->psname[
i ] & 0x80) )
1058 if(
t->ufamily.isEmpty() &&
t->family.isEmpty() )
1061 bool bReplace =
true;
1063 for(
i = 0;
i <
t->ufamily.getLength() && bReplace;
i++ )
1064 if(
t->ufamily[
i ] < 33 ||
t->ufamily[
i ] > 127 )
1068 t->psname =
t->family;
1080 if (sscanf(fname,
"/:FD:/%d%n", &nFD, &
n) == 1 && fname[
n] ==
'\0')
1082 lseek(nFD, 0, SEEK_SET);
1083 int nDupFd = dup(nFD);
1084 fd = nDupFd != -1 ? fdopen(nDupFd,
"rb") :
nullptr;
1088 fd = fopen(fname,
"rb");
1095 if (fread(buffer, 1, 12, fd) == 12) {
1102 fseek(fd, 0, SEEK_END);
1103 sal_uInt64 fileSize = ftell(fd);
1110 const int nMaxFontsPossible = fileSize / 528;
1111 if (nFonts > nMaxFontsPossible)
1113 SAL_WARN(
"vcl.fonts",
"font file " << fname <<
" claims to have "
1114 << nFonts <<
" fonts, but only "
1115 << nMaxFontsPossible <<
" are possible");
1116 nFonts = nMaxFontsPossible;
1139 if( (*ttf)->fileName().empty() )
1147 if (sscanf(fname,
"/:FD:/%d%n", &nFD, &
n) == 1 && fname[
n] ==
'\0')
1149 lseek(nFD, 0, SEEK_SET);
1153 fd = open(fname, O_RDONLY);
1160 if (fstat(fd, &st) == -1) {
1165 (*ttf)->fsize = st.st_size;
1171 if ((*ttf)->fsize == 0) {
1176 if (((*ttf)->ptr =
static_cast<sal_uInt8 *
>(mmap(
nullptr, (*ttf)->fsize, PROT_READ, MAP_SHARED, fd, 0))) == MAP_FAILED) {
1181 ret = (*ttf)->open(facenum);
1184 if (fd != -1)
close(fd);
1198 if( *ttf ==
nullptr )
1201 (*ttf)->fsize = nLen;
1215bool withinBounds(sal_uInt32 tdoffset, sal_uInt32 moreoffset, sal_uInt32 len, sal_uInt32 available)
1222 return result <= available;
1227 : m_nGlyphs(0xFFFFFFFF)
1231 , m_xCharMap(xCharMap)
1232 , m_bMicrosoftSymbolEncoded(false)
1283 sal_uInt32 table_size;
1294 if (((indexfmt != 0) && (indexfmt != 1)) || (
m_nUnitsPerEm <= 0))
1299 int k = (table_size / (indexfmt ? 4 : 2)) - 1;
1305 for (
int i = 0; i <= static_cast<int>(
m_nGlyphs); ++
i)
1310 int k = (table_size / 2) - 1;
1349 sal_uInt32 tdoffset = 0;
1353 if ((TTCTag == 0x00010000) || (TTCTag ==
T_true)) {
1355 }
else if (TTCTag ==
T_otto) {
1357 }
else if (TTCTag ==
T_ttcf) {
1358 if (!withinBounds(12, 4 * facenum,
sizeof(sal_uInt32),
fsize))
1371 if (withinBounds(tdoffset, 0, 4 +
sizeof(sal_uInt16),
fsize))
1378 for (
i = 0; i < static_cast<int>(
ntables);
i++)
1381 const sal_uInt32 nStart = tdoffset + 12;
1382 const sal_uInt32 nOffset = 16 *
i;
1383 if (withinBounds(nStart, nOffset,
sizeof(sal_uInt32),
fsize))
1386 tag =
static_cast<sal_uInt32
>(-1);
1404 default:
nIndex = -1;
break;
1407 if ((
nIndex >= 0) && withinBounds(nStart, nOffset, 12 +
sizeof(sal_uInt32),
fsize))
1409 sal_uInt32 nTableOffset =
GetUInt32(
ptr + nStart, nOffset + 8);
1417 if (facenum == sal_uInt32(~0))
1429 for (
p = pHead + 12;
p >
ptr; --
p)
1431 if(
p[0]==0x5F &&
p[1]==0x0F &&
p[2]==0x3C &&
p[3]==0xF5 ) {
1432 int nDelta = (pHead + 12) -
p;
1434 for(
int j = 0; j <
NUM_TAGS; ++j )
1454#if OSL_DEBUG_LEVEL > 1
1456 <<
" has bad table offset "
1458 <<
"d (tagnum=" <<
i <<
").");
1469#if OSL_DEBUG_LEVEL > 1
1471 <<
" has too big table (tagnum=" <<
i <<
").");
1494 sal_uInt32 glyflength;
1497 sal_uInt32 nNextOffset = ttf->
glyphOffset(glyphID + 1);
1498 if (nNextOffset > glyflength)
1502 if (nOffset > nNextOffset)
1505 if (std::find(glyphlist.begin(), glyphlist.end(), glyphID) != glyphlist.end())
1507 SAL_WARN(
"vcl.fonts",
"Endless loop found in a compound glyph.");
1511 glyphlist.push_back( glyphID );
1514 if (nOffset == nNextOffset)
1517 const auto* ptr = glyf + nOffset;
1518 sal_uInt32 nRemainingData = glyflength - nOffset;
1520 if (nRemainingData >= 10 &&
GetInt16(ptr, 0) == -1) {
1521 sal_uInt16 flags,
index;
1523 nRemainingData -= 10;
1525 if (nRemainingData < 4)
1527 SAL_WARN(
"vcl.fonts",
"short read");
1534 nRemainingData -= 4;
1537 sal_uInt32 nAdvance;
1551 if (nRemainingData < nAdvance)
1553 SAL_WARN(
"vcl.fonts",
"short read");
1557 nRemainingData -= nAdvance;
1565 sal_uInt16
const *glyphArray,
sal_uInt8 *encoding,
int nGlyphs,
1568 std::vector<ControlPoint> pa;
1569 std::unique_ptr<PSPathElement[]> path;
1573 TTGlyphMetrics metrics;
1576 const char *
const h01 =
"%%!PS-AdobeFont-%d.%d-%d.%d\n";
1577 const char *
const h02 =
"%% Creator: %s %s %s\n";
1578 const char *
const h09 =
"%% Original font name: %s\n";
1580 const char *
const h10 =
1582 "/PaintType 0 def\n"
1584 "/StrokeWidth 0 def\n";
1586 const char *
const h11 =
"/FontName (%s) cvn def\n";
1591 const char *
const h13 =
"/FontMatrix [.001 0 0 .001 0 0] def\n";
1592 const char *
const h14 =
"/FontBBox [%d %d %d %d] def\n";
1594 const char *
const h15=
1595 "/Encoding 256 array def\n"
1596 " 0 1 255 {Encoding exch /.notdef put} for\n";
1598 const char *
const h16 =
" Encoding %d /glyph%d put\n";
1599 const char *
const h17 =
"/XUID [103 0 0 16#%08" SAL_PRIXUINT32
" %d 16#%08" SAL_PRIXUINT32
" 16#%08" SAL_PRIXUINT32
"] def\n";
1601 const char *
const h30 =
"/CharProcs %d dict def\n";
1602 const char *
const h31 =
" CharProcs begin\n";
1603 const char *
const h32 =
" /.notdef {} def\n";
1604 const char *
const h33 =
" /glyph%d {\n";
1605 const char *
const h34 =
" } bind def\n";
1606 const char *
const h35 =
" end\n";
1608 const char *
const h40 =
1610 " exch /CharProcs get exch\n"
1611 " 2 copy known not\n"
1612 " {pop /.notdef} if\n"
1616 " 1 index /Encoding get exch get\n"
1617 " 1 index /BuildGlyph get exec\n"
1619 "currentdict end\n";
1621 const char *
const h41 =
"(%s) cvn exch definefont pop\n";
1625 if (!fname) fname = ttf->
psname.getStr();
1627 constexpr int bufmax = 256;
1630 snprintf(buf, bufmax, h01,
GetInt16(
table, 0),
GetUInt16(
table, 2),
GetInt16(
table, 4),
GetUInt16(
table, 6));
1634 snprintf(buf, bufmax, h09, ttf->
psname.getStr());
1637 snprintf(buf, bufmax,
"%s", h10);
1639 snprintf(buf, bufmax, h11, fname);
1653 snprintf(buf, bufmax, h17, rtl_crc32(0, ttf->
ptr, ttf->
fsize), nGlyphs, rtl_crc32(0, glyphArray, nGlyphs * 2), rtl_crc32(0, encoding, nGlyphs));
1655 snprintf(buf, bufmax,
"%s", h13);
1657 snprintf(buf, bufmax, h14,
XUnits(UPEm,
GetInt16(
table, 36)),
XUnits(UPEm,
GetInt16(
table, 38)),
XUnits(UPEm,
GetInt16(
table, 40)),
XUnits(UPEm,
GetInt16(
table, 42)));
1659 snprintf(buf, bufmax,
"%s", h15);
1662 for (
i = 0;
i < nGlyphs;
i++) {
1663 snprintf(buf, bufmax, h16, encoding[
i],
i);
1667 snprintf(buf, bufmax, h30, nGlyphs+1);
1669 snprintf(buf, bufmax,
"%s", h31);
1671 snprintf(buf, bufmax,
"%s", h32);
1674 for (
i = 0;
i < nGlyphs;
i++) {
1675 snprintf(buf, bufmax, h33,
i);
1688 snprintf(buf, bufmax,
"\t%d %d %d %d %d %d setcachedevice\n",
1689 wmode == 0 ?
XUnits(UPEm, metrics.aw) : 0,
1690 wmode == 0 ? 0 : -
XUnits(UPEm, metrics.ah),
1691 XUnits(UPEm, metrics.xMin),
1692 XUnits(UPEm, metrics.yMin),
1693 XUnits(UPEm, metrics.xMax),
1694 XUnits(UPEm, metrics.yMax));
1697 for (j = 0; j <
n; j++)
1699 switch (path[j].
type)
1702 snprintf(buf, bufmax,
"\t%d %d moveto\n",
XUnits(UPEm, path[j].x1),
XUnits(UPEm, path[j].y1));
1707 snprintf(buf, bufmax,
"\t%d %d lineto\n",
XUnits(UPEm, path[j].x1),
XUnits(UPEm, path[j].y1));
1712 snprintf(buf, bufmax,
"\t%d %d %d %d %d %d curveto\n",
XUnits(UPEm, path[j].x1),
XUnits(UPEm, path[j].y1),
XUnits(UPEm, path[j].x2),
XUnits(UPEm, path[j].y2),
XUnits(UPEm, path[j].x3),
XUnits(UPEm, path[j].y3));
1717 snprintf(buf, bufmax,
"\tclosepath\n");
1726 snprintf(buf, bufmax,
"\tfill\n");
1730 snprintf(buf, bufmax,
"%s", h34);
1735 snprintf(buf, bufmax,
"%s", h35);
1738 snprintf(buf, bufmax,
"%s", h40);
1740 snprintf(buf, bufmax, h41, fname);
1747 std::vector<sal_uInt8>& rOutBuffer,
1748 sal_uInt16
const *glyphArray,
1752 std::unique_ptr<TrueTypeTableGeneric> cvt, prep, fpgm, os2;
1753 std::unique_ptr<TrueTypeTableName>
name;
1754 std::unique_ptr<TrueTypeTableMaxp> maxp;
1755 std::unique_ptr<TrueTypeTableHhea> hhea;
1756 std::unique_ptr<TrueTypeTableHead> head;
1757 std::unique_ptr<TrueTypeTableGlyf> glyf;
1758 std::unique_ptr<TrueTypeTableCmap> cmap;
1759 std::unique_ptr<TrueTypeTablePost> post;
1767 std::vector<NameRecord> names;
1772 sal_uInt32 nTableSize;
1786 assert(
p !=
nullptr);
1798 std::unique_ptr<sal_uInt32[]> gID(
new sal_uInt32[nGlyphs]);
1800 for (
i = 0;
i < nGlyphs;
i++) {
1807 for (
i=0;
i < nGlyphs;
i++) {
1808 cmap->cmapAdd(0x010000, encoding[
i], gID[
i]);
1812 if ((
p = ttf->
table(
O_cvt, nTableSize)) !=
nullptr)
1837 nThickness, nFixedPitch));
1848#if OSL_DEBUG_LEVEL > 1
1850 << (
int) res <<
".");
1858void FillFontSubsetInfo(AbstractTrueTypeFont* ttf,
FontSubsetInfo& rInfo)
1863 rInfo.
m_aPSName = OUString::fromUtf8(aTTInfo.psname);
1874 rInfo.
m_nAscent = +aTTInfo.typoAscender;
1885bool CreateCFFfontSubset(
const unsigned char* pFontBytes,
int nByteLength,
1886 std::vector<sal_uInt8>& rOutBuffer,
const sal_GlyphId* pGlyphIds,
1898 rOutBuffer.resize(pStream->
TellEnd());
1900 auto nRead = pStream->
ReadBytes(rOutBuffer.data(), rOutBuffer.size());
1901 if (nRead != rOutBuffer.size())
1917 FillFontSubsetInfo(&rTTF, rInfo);
1923 return CreateCFFfontSubset(pCFF, nCFF, rOutBuffer, pGlyphIds, pEncoding,
1924 nOrigGlyphCount, rInfo);
1935 if (nOrigGlyphCount > 256)
1937 SAL_WARN(
"vcl.fonts",
"too many glyphs for subsetting");
1941 int nGlyphCount = nOrigGlyphCount;
1942 sal_uInt16 aShortIDs[256];
1946 int nNotDef = -1,
i;
1947 for (
i = 0;
i < nGlyphCount; ++
i)
1949 aTempEncs[
i] = pEncoding[
i];
1950 aShortIDs[
i] =
static_cast<sal_uInt16
>(pGlyphIds[
i]);
1961 if (nGlyphCount == 256)
1963 SAL_WARN(
"vcl.fonts",
"too many glyphs for subsetting");
1966 nNotDef = nGlyphCount++;
1969 aShortIDs[nNotDef] = aShortIDs[0];
1970 aTempEncs[nNotDef] = aTempEncs[0];
1980GlyphOffsets::GlyphOffsets(
sal_uInt8 *sfntP, sal_uInt32 sfntLen)
1983 sal_uInt16 numTables =
GetUInt16(sfntP, 4);
1984 sal_uInt32 locaLen = 0;
1985 sal_Int16 indexToLocFormat = 0;
1987 sal_uInt32 nMaxPossibleTables = sfntLen / (3*
sizeof(sal_uInt32));
1988 if (numTables > nMaxPossibleTables)
1990 SAL_WARN(
"vcl.fonts",
"GlyphOffsetsNew claimed to have "
1991 << numTables <<
" tables, but that's impossibly large");
1992 numTables = nMaxPossibleTables;
1995 for (sal_uInt16 i = 0;
i < numTables;
i++) {
1996 sal_uInt32 nLargestFixedOffsetPos = 12 + 16 *
i + 12;
1997 sal_uInt32 nMinSize = nLargestFixedOffsetPos +
sizeof(sal_uInt32);
1998 if (nMinSize > sfntLen)
2000 SAL_WARN(
"vcl.fonts",
"GlyphOffsetsNew claimed to have "
2001 << numTables <<
" tables, but only space for " << i);
2005 sal_uInt32 tag =
GetUInt32(sfntP, 12 + 16 * i);
2006 sal_uInt32 off =
GetUInt32(sfntP, 12 + 16 * i + 8);
2007 sal_uInt32 len =
GetUInt32(sfntP, nLargestFixedOffsetPos);
2012 }
else if (tag ==
T_head) {
2013 indexToLocFormat =
GetInt16(sfntP + off, 50);
2017 this->nGlyphs = locaLen / ((indexToLocFormat == 1) ? 4 : 2);
2018 assert(this->nGlyphs != 0);
2019 this->offs = std::make_unique<sal_uInt32[]>(this->nGlyphs);
2021 for (sal_uInt32 i = 0;
i < this->nGlyphs;
i++) {
2022 if (indexToLocFormat == 1) {
2034 SAL_WARN(
"vcl.fonts",
"DumpSfnts sfntLen is too short: "
2035 << sfntLen <<
" legal min is: " << 12);
2039 const sal_uInt32 nSpaceForTables = sfntLen - 12;
2040 const sal_uInt32 nTableSize = 16;
2041 const sal_uInt32 nMaxPossibleTables = nSpaceForTables/nTableSize;
2044 sal_uInt16
i, numTables =
GetUInt16(sfntP, 4);
2045 GlyphOffsets go(sfntP, sfntLen);
2048 if (numTables > nMaxPossibleTables)
2050 SAL_WARN(
"vcl.fonts",
"DumpSfnts claimed to have "
2051 << numTables <<
" tables, but only space for " << nMaxPossibleTables);
2052 numTables = nMaxPossibleTables;
2055 assert(numTables <= 9);
2057 std::unique_ptr<sal_uInt32[]> offs(
new sal_uInt32[numTables]);
2061 h.BlockWrite(sfntP, 12);
2062 h.BlockWrite(sfntP+12, 16 * numTables);
2064 for (
i=0;
i<numTables;
i++)
2066 sal_uInt32 nLargestFixedOffsetPos = 12 + 16 *
i + 12;
2067 sal_uInt32 nMinSize = nLargestFixedOffsetPos +
sizeof(sal_uInt32);
2068 if (nMinSize > sfntLen)
2070 SAL_WARN(
"vcl.fonts",
"DumpSfnts claimed to have "
2071 << numTables <<
" tables, but only space for " <<
i);
2075 sal_uInt32 tag =
GetUInt32(sfntP, 12 + 16 *
i);
2076 sal_uInt32 off =
GetUInt32(sfntP, 12 + 16 *
i + 8);
2079 SAL_WARN(
"vcl.fonts",
"DumpSfnts claims offset of "
2080 << off <<
" but max possible is " << sfntLen);
2084 sal_uInt32 len =
GetUInt32(sfntP, nLargestFixedOffsetPos);
2085 sal_uInt32 nMaxLenPossible = sfntLen - off;
2086 if (len > nMaxLenPossible)
2088 SAL_WARN(
"vcl.fonts",
"DumpSfnts claims len of "
2089 << len <<
" but only space for " << nMaxLenPossible);
2095 h.BlockWrite(pRecordStart, len);
2100 sal_uInt8 *eof = pRecordStart + nMaxLenPossible;
2101 for (sal_uInt32 j = 0; j < go.nGlyphs - 1; j++)
2103 sal_uInt32 nStartOffset = go.offs[j];
2104 sal_uInt8 *pSubRecordStart = glyf + nStartOffset;
2105 if (pSubRecordStart > eof)
2107 SAL_WARN(
"vcl.fonts",
"DumpSfnts start glyf claims offset of "
2108 << pSubRecordStart - sfntP <<
" but max possible is " << eof - sfntP);
2112 sal_uInt32 nEndOffset = go.offs[j + 1];
2113 sal_uInt8 *pSubRecordEnd = glyf + nEndOffset;
2114 if (pSubRecordEnd > eof)
2116 SAL_WARN(
"vcl.fonts",
"DumpSfnts end glyf offset of "
2117 << pSubRecordEnd - sfntP <<
" but max possible is " << eof - sfntP);
2121 sal_uInt32 l = pSubRecordEnd - pSubRecordStart;
2122 h.BlockWrite(pSubRecordStart, l);
2125 h.BlockWrite(pad, (4 - (len & 3)) & 3);
2134 sal_uInt16
const *glyphArray,
2138 std::unique_ptr<TrueTypeTable> head, hhea, maxp, cvt, prep, fpgm;
2139 std::unique_ptr<TrueTypeTableGlyf> glyf;
2150 assert(psname !=
nullptr);
2155 sal_uInt32 nTableSize;
2158 assert(
p !=
nullptr);
2159 head.reset(
new TrueTypeTableHead(
GetInt32(
p,
HEAD_fontRevision_offset),
GetUInt16(
p,
HEAD_flags_offset),
GetUInt16(
p,
HEAD_unitsPerEm_offset),
p+
HEAD_created_offset,
GetUInt16(
p,
HEAD_macStyle_offset),
GetUInt16(
p,
HEAD_lowestRecPPEM_offset),
GetInt16(
p,
HEAD_fontDirectionHint_offset)));
2175 if ((
p = ttf->
table(
O_cvt, nTableSize)) !=
nullptr)
2188 std::unique_ptr<sal_uInt16[]> gID(
new sal_uInt16[nGlyphs]);
2190 for (
i = 0;
i < nGlyphs;
i++) {
2191 gID[
i] =
static_cast<sal_uInt16
>(glyf->glyfAdd(
GetTTRawGlyphData(ttf, glyphArray[
i]), ttf));
2194 const int nGlyfCount =
static_cast<int>(glyf->glyfCount());
2199 std::vector<sal_uInt8> aOutBuffer;
2204 constexpr int bufmax = 256;
2207 snprintf(buf, bufmax,
"%%!PS-TrueTypeFont-%d.%d-%d.%d\n",
static_cast<int>(ver),
static_cast<int>(ver & 0xFF),
static_cast<int>(rev>>16),
static_cast<int>(rev & 0xFFFF));
2211 snprintf(buf, bufmax,
"%%- Font subset generated from a source font file: '%s'\n", ttf->
fileName().data());
2213 snprintf(buf, bufmax,
"%%- Original font name: %s\n", ttf->
psname.getStr());
2215 snprintf(buf, bufmax,
"%%- Original font family: %s\n", ttf->
family.getStr());
2217 snprintf(buf, bufmax,
"%%- Original font sub-family: %s\n", ttf->
subfamily.getStr());
2219 snprintf(buf, bufmax,
"11 dict begin\n");
2221 snprintf(buf, bufmax,
"/FontName (%s) cvn def\n", psname);
2223 snprintf(buf, bufmax,
"/PaintType 0 def\n");
2225 snprintf(buf, bufmax,
"/FontMatrix [1 0 0 1 0 0] def\n");
2227 snprintf(buf, bufmax,
"/FontBBox [%d %d %d %d] def\n",
XUnits(UPEm,
GetInt16(headP,
HEAD_xMin_offset)),
XUnits(UPEm,
GetInt16(headP,
HEAD_yMin_offset)),
XUnits(UPEm,
GetInt16(headP,
HEAD_xMax_offset)),
XUnits(UPEm,
GetInt16(headP,
HEAD_yMax_offset)));
2229 snprintf(buf, bufmax,
"/FontType 42 def\n");
2231 snprintf(buf, bufmax,
"/Encoding 256 array def\n");
2233 snprintf(buf, bufmax,
" 0 1 255 {Encoding exch /.notdef put} for\n");
2236 for (
i = 1;
i<nGlyphs;
i++) {
2237 snprintf(buf, bufmax,
"Encoding %d /glyph%u put\n", encoding[
i], gID[
i]);
2240 snprintf(buf, bufmax,
"/XUID [103 0 1 16#%08X %u 16#%08X 16#%08X] def\n",
static_cast<unsigned int>(rtl_crc32(0, ttf->
ptr, ttf->
fsize)),
static_cast<unsigned int>(nGlyphs),
static_cast<unsigned int>(rtl_crc32(0, glyphArray, nGlyphs * 2)),
static_cast<unsigned int>(rtl_crc32(0, encoding, nGlyphs)));
2243 DumpSfnts(outf, aOutBuffer.data(), aOutBuffer.size());
2246 snprintf(buf, bufmax,
"/CharStrings %d dict dup begin\n", nGlyphs);
2248 snprintf(buf, bufmax,
"/.notdef 0 def\n");
2250 for (
i = 1;
i < nGlyfCount;
i++) {
2251 snprintf(buf, bufmax,
"/glyph%d %d def\n",
i,
i);
2254 snprintf(buf, bufmax,
"end readonly def\n");
2257 snprintf(buf, bufmax,
"FontName currentdict end definefont pop\n");
2265 sal_uInt32 table_size;
2267 if (table_size < 46)
2292 sal_uInt32 table_size;
2294 if (table_size >= 42)
2315 if (table_size >= 12 +
sizeof(sal_uInt32))
2324 if (table_size >= 10 && UPEm != 0)
2337 sal_uInt32 hmtxlength;
2343 sal_uInt32 glyflength;
2348 sal_uInt32 nNextOffset = ttf->
glyphOffset(glyphID + 1);
2349 if (nNextOffset > glyflength)
2353 if (nOffset > nNextOffset)
2356 sal_uInt32
length = nNextOffset - nOffset;
2362 const size_t nChunkLen = ((
length + 1) & ~1);
2364 memcpy(
d->ptr.get(), srcptr,
length);
2366 d->compflag = (
GetInt16( srcptr, 0 ) < 0);
2369 d->compflag =
false;
2372 d->glyphID = glyphID;
2373 d->nbytes =
static_cast<sal_uInt16
>((
length + 1) & ~1);
2376 std::vector<ControlPoint> cp;
2381 for (
int i = 0;
i <
n;
i++)
2383 if (cp[
i].flags & 0x8000)
2386 d->npoints =
static_cast<sal_uInt16
>(
n);
2387 d->ncontours =
static_cast<sal_uInt16
>(
m);
2394 sal_uInt32 nAwOffset;
2395 sal_uInt32 nLsboffset;
2396 if (glyphID < ttf->horzMetricCount()) {
2397 nAwOffset = 4 * glyphID;
2398 nLsboffset = 4 * glyphID + 2;
2404 if (nAwOffset + 2 <= hmtxlength)
2408 SAL_WARN(
"vcl.fonts",
"hmtx offset " << nAwOffset <<
" not available");
2411 if (nLsboffset + 2 <= hmtxlength)
2415 SAL_WARN(
"vcl.fonts",
"hmtx offset " << nLsboffset <<
" not available");
2424 sal_uInt32 nTableSize;
2431#if OSL_DEBUG_LEVEL > 1
2432 SAL_WARN(
"vcl.fonts",
"O_name table too small.");
2443 const sal_uInt32 remaining_table_size = nTableSize-6;
2444 const sal_uInt32 nMinRecordSize = 12;
2445 const sal_uInt32 nMaxRecords = remaining_table_size / nMinRecordSize;
2446 if (
n > nMaxRecords)
2448 SAL_WARN(
"vcl.fonts",
"Parsing error in " << OUString::createFromAscii(ttf->
fileName()) <<
2449 ": " << nMaxRecords <<
" max possible entries, but " <<
2450 n <<
" claimed, truncating");
2456 for (
i = 0;
i <
n;
i++) {
2457 sal_uInt32 nLargestFixedOffsetPos = 6 + 10 + 12 *
i;
2458 sal_uInt32 nMinSize = nLargestFixedOffsetPos +
sizeof(sal_uInt16);
2459 if (nMinSize > nTableSize)
2461 SAL_WARN(
"vcl.fonts",
"Font " << OUString::createFromAscii(ttf->
fileName()) <<
" claimed to have "
2462 <<
n <<
" name records, but only space for " <<
i);
2471 sal_uInt32 nStrOffset =
GetUInt16(
table, nLargestFixedOffsetPos);
2473 if (nStrBase + nStrOffset + slen >= nTableSize)
2476 const sal_uInt32 rec_string = nStrBase + nStrOffset;
2477 const size_t available_space = rec_string > nTableSize ? 0 : (nTableSize - rec_string);
2478 if (slen <= available_space)
2480 nr[
i].sptr.resize(slen);
2481 memcpy(nr[
i].sptr.data(),
table + rec_string, slen);
2485 if( (nr[
i].platformID == 3) && (nr[
i].encodingID == 0) )
2486 nr[
i].encodingID = 1;
2490template<
size_t N>
static void
2491append(std::bitset<N> & rSet,
size_t const nOffset, sal_uInt32
const nValue)
2493 for (
size_t i = 0;
i < 32; ++
i)
2500 std::optional<std::bitset<UnicodeCoverage::MAX_UC_ENUM>> &rUnicodeRange,
2501 std::optional<std::bitset<CodePageCoverage::MAX_CP_ENUM>> &rCodePageRange,
2502 const unsigned char* pTable,
size_t nLength)
2508 rUnicodeRange = std::bitset<UnicodeCoverage::MAX_UC_ENUM>();
2516 rCodePageRange = std::bitset<CodePageCoverage::MAX_CP_ENUM>();
2535 sal_uInt16 aGlyphIds[ 256 ] = {};
2538 for (sal_uInt16 c = 32; c < 256; ++c)
2541 aGlyphIds[c] = c - 31;
2544 std::vector<sal_uInt8>
aBuffer;
tools::Rectangle m_aFontBBox
FontType m_nFontType
font-type of subset result
void LoadFont(FontType eInFontType, const unsigned char *pFontBytes, int nByteLength)
bool CreateFontSubset(FontType nOutFontTypeMask, SvStream *pOutFile, const char *pOutFontName, const sal_GlyphId *pGlyphIds, const sal_uInt8 *pEncodedIds, int nReqGlyphCount)
int m_nAscent
all metrics in PS font units
virtual sal_uInt64 TellEnd()
SvStream & WriteOString(std::string_view rStr)
sal_uInt64 Seek(sal_uInt64 nPos)
std::size_t ReadBytes(void *pData, std::size_t nSize)
SvStream * GetStream(StreamMode eMode)
virtual bool hasTable(sal_uInt32 ord) const =0
sal_uInt32 m_nHorzMetrics
virtual ~AbstractTrueTypeFont()
sal_uInt32 vertMetricCount() const
std::string const & fileName() const
bool m_bMicrosoftSymbolEncoded
sal_uInt32 horzMetricCount() const
sal_uInt32 m_nVertMetrics
virtual const sal_uInt8 * table(sal_uInt32 ord, sal_uInt32 &size) const =0
sal_uInt32 glyphCount() const
sal_uInt32 glyphOffset(sal_uInt32 glyphID) const
bool IsMicrosoftSymbolEncoded() const
FontCharMapRef m_xCharMap
AbstractTrueTypeFont(const char *fileName=nullptr, const FontCharMapRef xCharMap=nullptr)
std::vector< sal_uInt32 > m_aGlyphOffsets
SFErrCodes indexGlyphData()
sal_uInt32 unitsPerEm() const
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.
const sal_uInt8 * table(sal_uInt32 ord, sal_uInt32 &size) const override
bool hasTable(sal_uInt32 ord) const override
TrueTypeFont(const char *pFileName=nullptr, const FontCharMapRef xCharMap=nullptr)
SFErrCodes open(sal_uInt32 facenum)
std::array< struct TTFontTable_, NUM_TAGS > m_aTableList
Creates a new empty 'cmap' table.
Creates a new empty 'glyf' table.
Creates a new 'head' table for a TrueType font.
Creates a new 'hhea' table for a TrueType font.
Creates a new 'maxp' table based on an existing maxp table.
Creates a new 'name' table.
Creates a new 'post' table of one of the supported formats.
TOOLS_DLLPUBLIC fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1)
TOOLS_DLLPUBLIC fix16_t fix16_div(fix16_t inArg0, fix16_t inArg1)
bool HasMicrosoftSymbolCmap(const unsigned char *pCmap, int nLength)
@ TYPE1_PFB
PSType1 Postscript Font Binary.
@ CFF_FONT
CFF-container with PSType2 glyphs.
@ SFNT_TTF
SFNT container with TrueType glyphs.
SFErrCodes CreateTTFromTTGlyphs(AbstractTrueTypeFont *ttf, std::vector< sal_uInt8 > &rOutBuffer, sal_uInt16 const *glyphArray, sal_uInt8 const *encoding, int nGlyphs)
Generates a new TrueType font and dumps it to outf file.
void GetTTGlobalFontInfo(AbstractTrueTypeFont *ttf, TTGlobalFontInfo *info)
Returns global font information about the TrueType font.
SFErrCodes OpenTTFontBuffer(const void *pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont **ttf, const FontCharMapRef xCharMap)
TrueTypeFont constructor.
int CountTTCFonts(const char *fname)
Get the number of fonts contained in a TrueType collection.
int GetTTGlyphPoints(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vector< ControlPoint > &pointArray)
Extracts TrueType control points, and stores them in an allocated array pointed to by *pointArray.
bool GetTTGlobalFontHeadInfo(const AbstractTrueTypeFont *ttf, int &xMin, int &yMin, int &xMax, int &yMax, sal_uInt16 &macStyle)
Returns part of the head table info, normally collected by GetTTGlobalFontInfo.
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.
void CloseTTFont(TrueTypeFont *ttf)
TrueTypeFont destructor.
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.
SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont *ttf, SvStream *outf, const char *psname, sal_uInt16 const *glyphArray, sal_uInt8 *encoding, int nGlyphs)
Generates a new PostScript Type42 font and dumps it to outf file.
void GetTTNameRecords(AbstractTrueTypeFont const *ttf, std::vector< NameRecord > &nr)
Extracts all Name Records from the font and stores them in an allocated array of NameRecord structs.
SFErrCodes OpenTTFontFile(const char *fname, sal_uInt32 facenum, TrueTypeFont **ttf, const FontCharMapRef xCharMap)
TrueTypeFont constructor.
SFErrCodes CreateT3FromTTGlyphs(TrueTypeFont *ttf, SvStream *outf, const char *fname, sal_uInt16 const *glyphArray, sal_uInt8 *encoding, int nGlyphs, int wmode)
Generates a new PostScript Type 3 font and dumps it to outf file.
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
std::unique_ptr< sal_Int32[]> pData
tDoubleVectorPair cleanup(const css::uno::Sequence< double > &rXValues, const css::uno::Sequence< double > &rYValues, Pred aPred)
std::enable_if< std::is_signed< T >::value, bool >::type checked_add(T a, T b, T &result)
constexpr T saturating_add(T a, T b)
constexpr int HHEA_ascender_offset
constexpr int OS2_ulCodePageRange1_offset
constexpr int OS2_ulUnicodeRange4_offset
static void GetMetrics(AbstractTrueTypeFont const *ttf, sal_uInt32 glyphID, TTGlyphMetrics *metrics)
constexpr int OS2_fsType_offset
constexpr sal_uInt32 T_ttcf
constexpr int HHEA_lineGap_offset
constexpr int OS2_typoDescender_offset
static char toHex(sal_uInt8 nIndex)
constexpr int HEAD_lowestRecPPEM_offset
constexpr int OS2_Legacy_length
constexpr int OS2_usWeightClass_offset
constexpr int HEAD_fontRevision_offset
constexpr sal_uInt32 T_post
constexpr sal_uInt32 T_cvt
constexpr sal_uInt32 T_vhea
static OString nameExtract(const sal_uInt8 *name, int nTableSize, int n, int dbFlag, OUString *ucs2result)
constexpr sal_uInt32 T_loca
constexpr int HEAD_majorVersion_offset
constexpr int OS2_winAscent_offset
constexpr int HEAD_yMax_offset
constexpr int HHEA_caretSlopeRise_offset
constexpr sal_uInt32 T_otto
constexpr int GLYF_xMax_offset
SFErrCodes
Return value of OpenTTFont() and CreateT3FromTTGlyphs()
@ FontNo
incorrect logical font number of a TTC font
@ TtFormat
incorrect TrueType font format
@ Memory
memory allocation error
@ GlyphNum
incorrect number of glyphs
@ BadArg
incorrect arguments
constexpr int OS2_typoAscender_offset
struct TTGlobalFontInfo_ TTGlobalFontInfo
Return value of GetTTGlobalFontInfo()
constexpr int OS2_typoLineGap_offset
constexpr sal_uInt32 T_true
constexpr sal_uInt32 T_prep
constexpr sal_uInt32 T_glyf
const char *const modextra
constexpr int OS2_ulUnicodeRange3_offset
static F16Dot16 fixedMul(F16Dot16 a, F16Dot16 b)
static int XUnits(int unitsPerEm, int n)
constexpr int GLYF_numberOfContours_offset
const char *const modname
constexpr int OS2_ulCodePageRange2_offset
constexpr sal_uInt32 T_hhea
constexpr int OS2_panoseNbBytes_offset
static void append(std::bitset< N > &rSet, size_t const nOffset, sal_uInt32 const nValue)
constexpr int OS2_ulUnicodeRange2_offset
constexpr int HEAD_created_offset
constexpr int GLYF_yMax_offset
constexpr int HHEA_caretSlopeRun_offset
static void DumpSfnts(SvStream *outf, sal_uInt8 *sfntP, sal_uInt32 sfntLen)
constexpr int HEAD_flags_offset
static void GetNames(AbstractTrueTypeFont *t)
constexpr int HEAD_unitsPerEm_offset
bool getTTCoverage(std::optional< std::bitset< UnicodeCoverage::MAX_UC_ENUM > > &rUnicodeRange, std::optional< std::bitset< CodePageCoverage::MAX_CP_ENUM > > &rCodePageRange, const unsigned char *pTable, size_t nLength)
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 HEAD_fontDirectionHint_offset
constexpr int HEAD_xMin_offset
static sal_uInt32 GetUInt32(const sal_uInt8 *ptr, size_t offset)
constexpr int POST_isFixedPitch_offset
constexpr int POST_underlinePosition_offset
constexpr int GLYF_yMin_offset
static F16Dot16 fixedDiv(F16Dot16 a, F16Dot16 b)
bool CreateTTFfontSubset(vcl::AbstractTrueTypeFont &rTTF, std::vector< sal_uInt8 > &rOutBuffer, const sal_GlyphId *pGlyphIds, const sal_uInt8 *pEncoding, const int nOrigGlyphCount, FontSubsetInfo &rInfo)
constexpr int OS2_V1_length
constexpr int POST_italicAngle_offset
constexpr sal_uInt32 T_maxp
constexpr sal_uInt32 T_OS2
constexpr sal_uInt32 T_CFF
constexpr int GLYF_xMin_offset
constexpr int HEAD_indexToLocFormat_offset
static F16Dot16 fromF2Dot14(sal_Int16 n)
constexpr sal_uInt32 T_hmtx
constexpr sal_uInt32 T_name
constexpr int HEAD_macStyle_offset
static int GetTTGlyphOutline(AbstractTrueTypeFont *, sal_uInt32, std::vector< ControlPoint > &, TTGlyphMetrics *, std::vector< sal_uInt32 > *)
static sal_uInt16 GetUInt16(const sal_uInt8 *ptr, size_t offset)
constexpr sal_uInt32 T_fpgm
static sal_Int32 GetInt32(const sal_uInt8 *ptr, size_t offset)
static int BSplineToPSPath(ControlPoint const *srcA, int srcCount, std::unique_ptr< PSPathElement[]> &path)
constexpr int POST_underlineThickness_offset
constexpr int HHEA_descender_offset
static int GetCompoundTTOutline(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID, std::vector< ControlPoint > &pointArray, TTGlyphMetrics *metrics, std::vector< sal_uInt32 > &glyphlist)
constexpr int OS2_ulUnicodeRange1_offset
constexpr int HEAD_Length
static int findname(const sal_uInt8 *name, sal_uInt16 n, sal_uInt16 platformID, sal_uInt16 encodingID, sal_uInt16 languageID, sal_uInt16 nameID)
constexpr int OS2_panose_offset
constexpr sal_uInt32 T_cmap
static int GetSimpleTTOutline(AbstractTrueTypeFont const *ttf, sal_uInt32 glyphID, std::vector< ControlPoint > &pointArray, TTGlyphMetrics *metrics)
constexpr sal_uInt32 T_vmtx
constexpr int OS2_winDescent_offset
static F16Dot16 fixedMulDiv(F16Dot16 a, F16Dot16 b, F16Dot16 c)
constexpr int OS2_usWidthClass_offset
@ WE_HAVE_AN_X_AND_Y_SCALE
sal_Int32 F16Dot16
fixed: 16.16
constexpr int OS2_V0_length
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
int TestFontSubset(const void *data, sal_uInt32 size)
ControlPoint structure used by GetTTGlyphPoints()
sal_Int16 y
Y coordinate in EmSquare units
sal_Int16 x
X coordinate in EmSquare units
sal_uInt32 flags
00000000 00000000 e0000000 bbbbbbbb
Structure used by the TrueType Creator and GetRawGlyphData()
Return value of GetTTGlobalFontInfo()
int italicAngle
in counter-clockwise degrees * 65536
OString family
family name
int ascender
typographic ascent.
int typoDescender
OS/2 portable typographic descender
int yMin
global bounding box: yMin
int winAscent
ascender metric for Windows
int xMin
global bounding box: xMin
int typoAscender
OS/2 portable typographic ascender
sal_uInt8 panose[10]
PANOSE classification number
int width
value of WidthClass or 0 if can't be determined
int typoLineGap
OS/2 portable typographic line gap
int weight
value of WeightClass or 0 if can't be determined
int xMax
global bounding box: xMax
sal_uInt32 typeFlags
type flags (copyright bits)
OUString usubfamily
subfamily name UCS2
int winDescent
descender metric for Windows
OString psname
PostScript name
int linegap
typographic line gap. Negative values are treated as zero in Win 3.1, System 6 and System 7.
int descender
typographic descent.
OUString ufamily
family name UCS2
bool microsoftSymbolEncoded
true: MS symbol encoded
int pitch
0: proportional font, otherwise: monospaced
sal_uInt16 macStyle
macstyle bits from 'HEAD' table
OString subfamily
subfamily name
int yMax
global bounding box: yMax
std::unique_ptr< char[]> aBuffer