Serenity Operating System
at master 81 lines 2.8 kB view raw
1/* 2 * Copyright (c) 2022, Nico Weber <thakis@chromium.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibGfx/Font/OpenType/Cmap.h> 8#include <LibTest/TestCase.h> 9 10TEST_CASE(test_cmap_format_4) 11{ 12 // clang-format off 13 // Big endian. 14 u8 cmap_table[] = 15 { 16 // https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#cmap-header 17 0, 0, // uint16 version 18 0, 1, // uint16 numTables 19 20 // https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#encoding-records-and-encodings 21 0, 0, // uint16 platformID, 0 means "Unicode" 22 0, 3, // uint16 encodingID, 3 means "BMP only" for platformID==0. 23 0, 0, 0, 12, // Offset32 to encoding subtable. 24 25 // https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values 26 0, 4, // uint16 format = 4 27 0, 42, // uint16 length in bytes 28 0, 0, // uint16 language, must be 0 29 0, 6, // segCount * 2 30 0, 4, // searchRange 31 0, 1, // entrySelector 32 0, 2, // rangeShift 33 34 // endCode array, last entry must be 0xffff. 35 0, 128, 36 1, 0, 37 0xff, 0xff, 38 39 0, 0, // uint16 reservedPad 40 41 // startCode array 42 0, 16, 43 1, 0, 44 0xff, 0xff, 45 46 // delta array 47 0, 0, 48 0, 10, 49 0, 0, 50 51 // glyphID array 52 0, 0, 53 0, 0, 54 0, 0, 55 }; 56 // clang-format on 57 auto cmap = OpenType::Cmap::from_slice({ cmap_table, sizeof cmap_table }).value(); 58 cmap.set_active_index(0); 59 60 // Format 4 can't handle code points > 0xffff. 61 62 // First range is 16..128. 63 EXPECT_EQ(cmap.glyph_id_for_code_point(15), 0u); 64 EXPECT_EQ(cmap.glyph_id_for_code_point(16), 16u); 65 EXPECT_EQ(cmap.glyph_id_for_code_point(128), 128u); 66 EXPECT_EQ(cmap.glyph_id_for_code_point(129), 0u); 67 68 // Second range is 256..256, with delta 10. 69 EXPECT_EQ(cmap.glyph_id_for_code_point(255), 0u); 70 EXPECT_EQ(cmap.glyph_id_for_code_point(256), 266u); 71 EXPECT_EQ(cmap.glyph_id_for_code_point(257), 0u); 72 73 // Third range is 0xffff..0xffff. 74 // From https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values: 75 // "the final start code and endCode values must be 0xFFFF. This segment need not contain any valid mappings. 76 // (It can just map the single character code 0xFFFF to missingGlyph). However, the segment must be present." 77 // FIXME: Make OpenType::Cmap::from_slice() reject inputs where this isn't true. 78 EXPECT_EQ(cmap.glyph_id_for_code_point(0xfeff), 0u); 79 EXPECT_EQ(cmap.glyph_id_for_code_point(0xffff), 0xffffu); 80 EXPECT_EQ(cmap.glyph_id_for_code_point(0x1'0000), 0u); 81}