#include #ifdef TRACE_BLOCKS #define KBTS_INSTRUMENT_BLOCK_BEGIN(Name) printf("<%s>\n", #Name) #define KBTS_INSTRUMENT_BLOCK_END(Name) printf("\n", #Name) #define KBTS_INSTRUMENT_FUNCTION_BEGIN #define KBTS_INSTRUMENT_FUNCTION_END #endif #include "kb_text_shape.h" #include "kb_text_shape.inc" void hs_ShapeCurrentCodepointsIterator(kbts_shape_context *Context, kbts_shape_codepoint_iterator *It) { *It = kbts__InputCodepointIterator(Context, 0, Context->InputCodepointCount); } void hs_CodepointToGlyph(kbts_font *Font, int Codepoint, kbts_glyph_config *Config, int UserId, kbts_glyph *Glyph) { *Glyph = kbts_CodepointToGlyph(Font, Codepoint, Config, UserId); } void hs_ActiveGlyphIterator(kbts_glyph_storage *Storage, kbts_glyph_iterator *It) { *It = kbts_ActiveGlyphIterator(Storage); } kbts_load_font_error hs_FontFromFile(const char *FileName, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData, void **FileData, int *FileSize_, kbts_font *Font) { *Font = kbts_FontFromFile(FileName, FontIndex, Allocator, AllocatorData, FileData, FileSize_); return Font->Error; } kbts_load_font_error hs_FontFromMemory(void *FileData, int FileSize, int FontIndex, kbts_allocator_function *Allocator, void *AllocatorData, kbts_font *Font) { *Font = kbts_FontFromMemory(FileData, FileSize, FontIndex, Allocator, AllocatorData); return Font->Error; } uint16_t hs_GetCapHeight(kbts_font *Font) { if (!Font || !Font->Blob) return 0; kbts_blob_header *Header = Font->Blob; kbts_blob_table *TableEntry = &Header->Tables[KBTS_BLOB_TABLE_ID_OS2]; if (TableEntry->Length < 90) return 0; uint8_t *BlobStart = (uint8_t *)Header; uint8_t *TableData = BlobStart + TableEntry->OffsetFromStartOfFile; uint16_t CapHeight; memcpy(&CapHeight, TableData + 88, sizeof(uint16_t)); return CapHeight; } uint16_t hs_GetUnitsPerEm(kbts_font *Font) { if (!Font || !Font->Blob) return 0; kbts_blob_header *Header = Font->Blob; // Access the entry for the 'head' table kbts_blob_table *HeadTableEntry = &Header->Tables[KBTS_BLOB_TABLE_ID_HEAD]; // Ensure the table exists and is large enough (min length is usually 54 bytes) if (HeadTableEntry->Length < 20) return 0; // Calculate the pointer to the table data // Note: Offsets are relative to the start of the blob header uint8_t *BlobStart = (uint8_t *)Header; uint8_t *HeadTableData = BlobStart + HeadTableEntry->OffsetFromStartOfFile; // The library stores the Blob data in Native Endian. // We use memcpy to safely read the 16-bit integer without violating alignment rules. uint16_t UnitsPerEm; memcpy(&UnitsPerEm, HeadTableData + 18, sizeof(uint16_t)); return UnitsPerEm; }