mirror of
https://github.com/reactos/wine.git
synced 2025-02-22 05:40:50 +00:00
dwrite: Implement TryGetFontTable and ReleaseFontTable.
This commit is contained in:
parent
26977d4a4b
commit
bc77ee6818
@ -94,3 +94,4 @@ extern HRESULT font_create_fontface(IDWriteFactory *iface, DWRITE_FONT_FACE_TYPE
|
||||
|
||||
/* Opentype font table functions */
|
||||
extern HRESULT analyze_opentype_font(const void* font_data, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported) DECLSPEC_HIDDEN;
|
||||
extern HRESULT find_font_table(IDWriteFontFileStream *stream, UINT32 font_index, UINT32 tag, const void** table_data, void** table_context, UINT32 *table_size, BOOL* found) DECLSPEC_HIDDEN;
|
||||
|
@ -156,6 +156,14 @@ struct dwrite_font {
|
||||
WCHAR *facename;
|
||||
};
|
||||
|
||||
#define DWRITE_FONTTABLE_MAGIC 0xededfafa
|
||||
|
||||
struct dwrite_fonttable {
|
||||
UINT32 magic;
|
||||
LPVOID context;
|
||||
UINT32 file_index;
|
||||
};
|
||||
|
||||
struct dwrite_fontface {
|
||||
IDWriteFontFace IDWriteFontFace_iface;
|
||||
LONG ref;
|
||||
@ -384,14 +392,65 @@ static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace *iface, UIN
|
||||
const void **table_data, UINT32 *table_size, void **context, BOOL *exists)
|
||||
{
|
||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
|
||||
FIXME("(%p)->(%u %p %p %p %p): stub\n", This, table_tag, table_data, table_size, context, exists);
|
||||
return E_NOTIMPL;
|
||||
if (This->is_system)
|
||||
{
|
||||
FIXME("(%p)->(%u %p %p %p %p): stub\n", This, table_tag, table_data, table_size, context, exists);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
int i;
|
||||
struct dwrite_fonttable *table;
|
||||
|
||||
TRACE("(%p)->(%u %p %p %p %p)\n", This, table_tag, table_data, table_size, context, exists);
|
||||
|
||||
table = heap_alloc(sizeof(struct dwrite_fonttable));
|
||||
table->magic = DWRITE_FONTTABLE_MAGIC;
|
||||
if (!table)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
*exists = FALSE;
|
||||
for (i = 0; i < This->file_count && !(*exists); i++)
|
||||
{
|
||||
IDWriteFontFileStream *stream;
|
||||
hr = _dwritefontfile_GetFontFileStream(This->files[i], &stream);
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
table->file_index = i;
|
||||
|
||||
hr = find_font_table(stream, This->index, table_tag, table_data, &table->context, table_size, exists);
|
||||
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
}
|
||||
if (FAILED(hr) && !*exists)
|
||||
heap_free(table);
|
||||
else
|
||||
*context = (LPVOID)table;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace *iface, void *table_context)
|
||||
{
|
||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
|
||||
FIXME("(%p)->(%p): stub\n", This, table_context);
|
||||
struct dwrite_fonttable *table = (struct dwrite_fonttable *)table_context;
|
||||
IDWriteFontFileStream *stream;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)->(%p)\n", This, table_context);
|
||||
|
||||
if (table->magic != DWRITE_FONTTABLE_MAGIC)
|
||||
{
|
||||
TRACE("Invalid table magic\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hr = _dwritefontfile_GetFontFileStream(This->files[table->file_index], &stream);
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, table->context);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
heap_free(table);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace *iface, FLOAT emSize,
|
||||
|
@ -47,6 +47,21 @@ typedef struct {
|
||||
DWORD OffsetTable[1];
|
||||
} TTC_Header_V1;
|
||||
|
||||
typedef struct {
|
||||
DWORD version;
|
||||
WORD numTables;
|
||||
WORD searchRange;
|
||||
WORD entrySelector;
|
||||
WORD rangeShift;
|
||||
} TTC_SFNT_V1;
|
||||
|
||||
typedef struct {
|
||||
CHAR tag[4];
|
||||
DWORD checkSum;
|
||||
DWORD offset;
|
||||
DWORD length;
|
||||
} TT_TableRecord;
|
||||
|
||||
HRESULT analyze_opentype_font(const void* font_data, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported)
|
||||
{
|
||||
/* TODO: Do font validation */
|
||||
@ -81,3 +96,76 @@ HRESULT analyze_opentype_font(const void* font_data, UINT32* font_count, DWRITE_
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT find_font_table(IDWriteFontFileStream *stream, UINT32 font_index, UINT32 tag, const void** table_data, void** table_context, UINT32 *table_size, BOOL* found)
|
||||
{
|
||||
const CHAR *first_data;
|
||||
void *first_context;
|
||||
HRESULT hr;
|
||||
TTC_SFNT_V1 *font_header = NULL;
|
||||
void *sfnt_context;
|
||||
TT_TableRecord *table_record = NULL;
|
||||
void *table_record_context;
|
||||
int i;
|
||||
int table_count;
|
||||
int table_offset = 0;
|
||||
|
||||
*found = FALSE;
|
||||
|
||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&first_data, 0, 4, &first_context);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (DWRITE_MAKE_OPENTYPE_TAG(first_data[0], first_data[1], first_data[2], first_data[3]) == MS_TTCF_TAG)
|
||||
{
|
||||
const TTC_Header_V1 *ttc_header;
|
||||
void * ttc_context;
|
||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&ttc_header, 0, sizeof(*ttc_header), &ttc_context);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
table_offset = GET_BE_DWORD(ttc_header->OffsetTable[0]);
|
||||
if (font_index >= GET_BE_DWORD(ttc_header->numFonts))
|
||||
hr = E_INVALIDARG;
|
||||
else
|
||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&font_header, table_offset, sizeof(*font_header), &sfnt_context);
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, ttc_context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (font_index > 0)
|
||||
hr = E_INVALIDARG;
|
||||
else
|
||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&font_header, 0, sizeof(*font_header), &sfnt_context);
|
||||
}
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, first_context);
|
||||
}
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
table_count = GET_BE_WORD(font_header->numTables);
|
||||
table_offset += sizeof(*font_header);
|
||||
for (i = 0; i < table_count; i++)
|
||||
{
|
||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&table_record, table_offset, sizeof(*table_record), &table_record_context);
|
||||
if (FAILED(hr))
|
||||
break;
|
||||
if (DWRITE_MAKE_OPENTYPE_TAG(table_record->tag[0], table_record->tag[1], table_record->tag[2], table_record->tag[3]) == tag)
|
||||
break;
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, table_record_context);
|
||||
table_offset += sizeof(*table_record);
|
||||
}
|
||||
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, sfnt_context);
|
||||
if (SUCCEEDED(hr) && i < table_count)
|
||||
{
|
||||
int offset = GET_BE_DWORD(table_record->offset);
|
||||
int length = GET_BE_DWORD(table_record->length);
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, table_record_context);
|
||||
|
||||
*found = TRUE;
|
||||
*table_size = length;
|
||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, table_data, offset, length, table_context);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user