HRESULT opentype_get_font_table(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_TYPE type, UINT32 font_index, UINT32 tag, const void **table_data, void **table_context, UINT32 *table_size, BOOL *found) { HRESULT hr; TTC_SFNT_V1 *font_header = NULL; void *sfnt_context; TT_TableRecord *table_record = NULL; void *table_record_context; int table_count, table_offset = 0; int i; if (found) *found = FALSE; if (table_size) *table_size = 0; if (type == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) { 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 hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&font_header, 0, sizeof(*font_header), &sfnt_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); if (found) *found = TRUE; if (table_size) *table_size = length; hr = IDWriteFontFileStream_ReadFileFragment(stream, table_data, offset, length, table_context); } return hr; }
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 */ const char* tag = font_data; *supported = FALSE; *file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN; if (face_type) *face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN; *font_count = 0; if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_TTCF_TAG) { const TTC_Header_V1 *header = font_data; *font_count = GET_BE_DWORD(header->numFonts); *file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION; if (face_type) *face_type = DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION; *supported = TRUE; } else if (GET_BE_DWORD(*(DWORD*)font_data) == 0x10000) { *font_count = 1; *file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE; if (face_type) *face_type = DWRITE_FONT_FACE_TYPE_TRUETYPE; *supported = TRUE; } else if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_OTTO_TAG) { *file_type = DWRITE_FONT_FILE_TYPE_CFF; } return S_OK; }
static int compare_group(const void *a, const void* b) { const DWORD *chr = a; const CMAP_SegmentedCoverage_group *group = b; if (*chr < GET_BE_DWORD(group->startCharCode)) return -1; if (*chr > GET_BE_DWORD(group->endCharCode)) return 1; return 0; }
HRESULT opentype_cmap_get_unicode_ranges(void *data, UINT32 max_count, DWRITE_UNICODE_RANGE *ranges, UINT32 *count) { CMAP_Header *CMAP_Table = data; int i, k = 0; if (!CMAP_Table) return E_FAIL; *count = opentype_cmap_get_unicode_ranges_count(CMAP_Table); for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables) && k < max_count; i++) { WORD type; WORD *table; int j; if (GET_BE_WORD(CMAP_Table->tables[i].platformID) != 3) continue; table = (WORD*)(((BYTE*)CMAP_Table) + GET_BE_DWORD(CMAP_Table->tables[i].offset)); type = GET_BE_WORD(*table); TRACE("table type %i\n", type); switch (type) { case OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING: { CMAP_SegmentMapping_0 *format = (CMAP_SegmentMapping_0*)table; UINT16 segment_count = GET_BE_WORD(format->segCountX2)/2; UINT16 *startCode = (WORD*)((BYTE*)format + sizeof(CMAP_SegmentMapping_0) + (sizeof(WORD) * segment_count)); for (j = 0; j < segment_count && GET_BE_WORD(format->endCode[j]) < 0xffff && k < max_count; j++, k++) { ranges[k].first = GET_BE_WORD(startCode[j]); ranges[k].last = GET_BE_WORD(format->endCode[j]); } break; } case OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE: { CMAP_SegmentedCoverage *format = (CMAP_SegmentedCoverage*)table; for (j = 0; j < GET_BE_DWORD(format->nGroups) && k < max_count; j++, k++) { ranges[k].first = GET_BE_DWORD(format->groups[j].startCharCode); ranges[k].last = GET_BE_DWORD(format->groups[j].endCharCode); } break; } default: FIXME("table type %i unhandled.\n", type); } } return *count > max_count ? E_NOT_SUFFICIENT_BUFFER : S_OK; }
static void CMAP12_GetGlyphIndex(CMAP_SegmentedCoverage* format, UINT32 utf32c, UINT16 *pgi) { CMAP_SegmentedCoverage_group *group; group = bsearch(&utf32c, format->groups, GET_BE_DWORD(format->nGroups), sizeof(CMAP_SegmentedCoverage_group), compare_group); if (group) { DWORD offset = utf32c - GET_BE_DWORD(group->startCharCode); *pgi = GET_BE_DWORD(group->startGlyphID) + offset; } }
void opentype_cmap_get_glyphindex(void *data, UINT32 utf32c, UINT16 *pgi) { CMAP_Header *CMAP_Table = data; int i; *pgi = 0; for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++) { WORD type; WORD *table; if (GET_BE_WORD(CMAP_Table->tables[i].platformID) != 3) continue; table = (WORD*)(((BYTE*)CMAP_Table) + GET_BE_DWORD(CMAP_Table->tables[i].offset)); type = GET_BE_WORD(*table); TRACE("table type %i\n", type); switch (type) { case OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING: CMAP4_GetGlyphIndex((CMAP_SegmentMapping_0*) table, utf32c, pgi); break; case OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE: CMAP12_GetGlyphIndex((CMAP_SegmentedCoverage*) table, utf32c, pgi); break; default: TRACE("table type %i unhandled.\n", type); } if (*pgi) return; } }
void KeyEventHandler::process( util::Buffer *msg ) { if (!_onKeyEvent.empty()) { util::BYTE *payload = MSG_PAYLOAD(msg->buffer()); util::DWORD value = GET_BE_DWORD( payload ); util::BYTE isUp = GET_BYTE(payload+4); _onKeyEvent( static_cast<util::key::type>( value ), (isUp == 1) ); } }
HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported) { /* TODO: Do font validation */ DWRITE_FONT_FACE_TYPE face; const void *font_data; const char* tag; void *context; HRESULT hr; hr = IDWriteFontFileStream_ReadFileFragment(stream, &font_data, 0, sizeof(TTC_Header_V1), &context); if (FAILED(hr)) return hr; tag = font_data; *file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN; face = DWRITE_FONT_FACE_TYPE_UNKNOWN; *font_count = 0; if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_TTCF_TAG) { const TTC_Header_V1 *header = font_data; *font_count = GET_BE_DWORD(header->numFonts); *file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION; face = DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION; } else if (GET_BE_DWORD(*(DWORD*)font_data) == 0x10000) { *font_count = 1; *file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE; face = DWRITE_FONT_FACE_TYPE_TRUETYPE; } else if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_OTTO_TAG) { *file_type = DWRITE_FONT_FILE_TYPE_CFF; face = DWRITE_FONT_FACE_TYPE_CFF; } if (face_type) *face_type = face; *supported = is_face_type_supported(face); IDWriteFontFileStream_ReleaseFileFragment(stream, context); return S_OK; }
static BOOL get_glyf_pos(TYPE42 *t42, DWORD index, DWORD *start, DWORD *end) { WORD loca_format = GET_BE_WORD(t42->tables[t42->head_tab].data + 50); TRACE("loca_format = %d\n", loca_format); switch(loca_format) { case 0: *start = GET_BE_WORD(((WORD*)t42->tables[t42->loca_tab].data) + index); *start <<= 1; *end = GET_BE_WORD(((WORD*)t42->tables[t42->loca_tab].data) + index + 1); *end <<= 1; break; case 1: *start = GET_BE_DWORD(((DWORD*)t42->tables[t42->loca_tab].data) + index); *end = GET_BE_DWORD(((DWORD*)t42->tables[t42->loca_tab].data) + index + 1); break; default: ERR("Unknown loca_format %d\n", loca_format); return FALSE; } return TRUE; }
static UINT32 opentype_cmap_get_unicode_ranges_count(const CMAP_Header *CMAP_Table) { UINT32 count = 0; int i; for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++) { WORD type; WORD *table; if (GET_BE_WORD(CMAP_Table->tables[i].platformID) != 3) continue; table = (WORD*)(((BYTE*)CMAP_Table) + GET_BE_DWORD(CMAP_Table->tables[i].offset)); type = GET_BE_WORD(*table); TRACE("table type %i\n", type); switch (type) { case OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING: { CMAP_SegmentMapping_0 *format = (CMAP_SegmentMapping_0*)table; count += GET_BE_WORD(format->segCountX2)/2; break; } case OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE: { CMAP_SegmentedCoverage *format = (CMAP_SegmentedCoverage*)table; count += GET_BE_DWORD(format->nGroups); break; } default: FIXME("table type %i unhandled.\n", type); } } return count; }
VOID OpenType_CMAP_GetGlyphIndex(LPVOID data, DWORD utf32c, LPWORD pgi, DWORD flags) { int i; CMAP_Header *CMAP_Table = NULL; if (flags & GGI_MARK_NONEXISTING_GLYPHS) *pgi = 0xffff; else *pgi = 0; CMAP_Table = data; for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++) { WORD type; WORD *table; if (GET_BE_WORD(CMAP_Table->tables[i].platformID) != 3) continue; table = (WORD*)(((BYTE*)CMAP_Table) + GET_BE_DWORD(CMAP_Table->tables[i].offset)); type = GET_BE_WORD(*table); TRACE("Type %i\n", type); /* Break when we find a handled type */ switch(type) { case 4: CMAP4_GetGlyphIndex((CMAP_SegmentMapping_0*) table, utf32c, pgi); break; case 12: CMAP12_GetGlyphIndex((CMAP_SegmentedCoverage*) table, utf32c, pgi); break; default: TRACE("Type %i unhandled.\n", type); } } }