Unify QFontEngine::getSfntTableData() behavior on all platforms

Being a most significant method in the font API,
getSfntTableData() must behave in exactly the same way on all platforms.
Briefly, it must return true if the table exists in the font,
despite the other params, and always stores the table data length
in 'length' param, thus reporting the amount of bytes actually
needed to store the table data in a buffer.

Change-Id: I7a15465020c1ea818ea46a05ea3b9b7e1cd60d14
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
bb10
Konstantin Ritt 2014-03-02 01:52:52 +02:00 committed by The Qt Project
parent 5cd7390ba9
commit 4c7082162d
7 changed files with 30 additions and 14 deletions

View File

@ -937,14 +937,31 @@ void QFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metr
addGlyphsToPath(&glyph, &p, 1, path, QFlag(0));
}
/*!
Returns \c true if the font table idetified by \a tag exists in the font;
returns \c false otherwise.
If \a buffer is NULL, stores the size of the buffer required for the font table data,
in bytes, in \a length. If \a buffer is not NULL and the capacity
of the buffer, passed in \a length, is sufficient to store the font table data,
also copies the font table data to \a buffer.
Note: returning \c false when the font table exists could lead to an undefined behavior.
*/
bool QFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
Q_UNUSED(tag)
Q_UNUSED(buffer)
Q_UNUSED(length)
return false;
}
QByteArray QFontEngine::getSfntTable(uint tag) const
{
QByteArray table;
uint len = 0;
if (!getSfntTableData(tag, 0, &len))
return table;
if (!len)
return table;
table.resize(len);
if (!getSfntTableData(tag, reinterpret_cast<uchar *>(table.data()), &len))
return QByteArray();

View File

@ -125,6 +125,7 @@ static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *leng
FT_ULong len = *length;
result = FT_Load_Sfnt_Table(face, tag, 0, buffer, &len) == FT_Err_Ok;
*length = len;
Q_ASSERT(!result || int(*length) > 0);
}
return result;

View File

@ -144,8 +144,8 @@ public:
};
virtual Properties properties() const;
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
QByteArray getSfntTable(uint /*tag*/) const;
virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const { return false; }
QByteArray getSfntTable(uint tag) const;
virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
struct FaceId {
FaceId() : index(0), encoding(0) {}

View File

@ -625,7 +625,7 @@ _hb_qt_reference_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data)
Q_ASSERT(get_font_table);
uint length = 0;
if (Q_UNLIKELY(!get_font_table(data->user_data, tag, 0, &length) || length == 0))
if (Q_UNLIKELY(!get_font_table(data->user_data, tag, 0, &length)))
return hb_blob_get_empty();
char *buffer = (char *)malloc(length);

View File

@ -659,16 +659,13 @@ bool QCoreTextFontEngine::canRender(const QChar *string, int len)
bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
if (!table || !length)
if (!table)
return false;
CFIndex tableLength = CFDataGetLength(table);
int availableLength = *length;
*length = tableLength;
if (buffer) {
if (tableLength > availableLength)
return false;
if (buffer && int(*length) >= tableLength)
CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
}
*length = tableLength;
Q_ASSERT(int(*length) > 0);
return true;
}

View File

@ -1032,6 +1032,7 @@ bool QWindowsFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length)
SelectObject(hdc, hfont);
DWORD t = qbswap<quint32>(tag);
*length = GetFontData(hdc, t, 0, buffer, *length);
Q_ASSERT(*length == GDI_ERROR || int(*length) > 0);
return *length != GDI_ERROR;
}

View File

@ -282,8 +282,8 @@ bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, ui
ret = true;
if (buffer && *length >= tableSize)
memcpy(buffer, tableData, tableSize);
else
*length = tableSize;
*length = tableSize;
Q_ASSERT(int(*length) > 0);
}
m_directWriteFontFace->ReleaseFontTable(tableContext);
} else {