diff options
Diffstat (limited to 'thirdparty')
344 files changed, 15657 insertions, 11050 deletions
diff --git a/thirdparty/README.md b/thirdparty/README.md index 0d5f3dd4c4..a918acbe77 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -115,7 +115,7 @@ commits. ## enet - Upstream: http://enet.bespin.org -- Version: 1.3.17 (e0e7045b7e056b454b5093cb34df49dc4cee0bee, 2020) +- Version: git (ea4607a90dbfbcf4da2669ea998585253d8e70b1, 2023) - License: MIT Files extracted from upstream source: @@ -178,7 +178,7 @@ Files extracted from upstream source: ## freetype - Upstream: https://www.freetype.org -- Version: 2.13.0 (de8b92dd7ec634e9e2b25ef534c54a3537555c11, 2023) +- Version: 2.13.1 (e4586d960f339cf75e2e0b34aee30a0ed8353c0d, 2023) - License: FreeType License (BSD-like) Files extracted from upstream source: @@ -250,7 +250,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 7.3.0 (4584bcdc326564829d3cee3572386c90e4fd1974, 2023) +- Version: 8.0.0 (b4305532a7746422e0b615eee6304119c1092fd8, 2023) - License: MIT Files extracted from upstream source: @@ -258,13 +258,13 @@ Files extracted from upstream source: - `AUTHORS`, `COPYING`, `THANKS` - from the `src` folder, recursively - all the `*.c`, `*.cc`, `*.h`, `*.hh` files - - _except_ `main.cc`, `harfbuzz*.cc`, `failing-alloc.c`, `test*.cc` + - _except_ `main.cc`, `harfbuzz*.cc`, `failing-alloc.c`, `test*.cc`, `hb-wasm*.*` ## icu4c - Upstream: https://github.com/unicode-org/icu -- Version: 73.1 (5861e1fd52f1d7673eee38bc3c965aa18b336062, 2023) +- Version: 73.2 (680f521746a3bd6a86f25f25ee50a62d88b489cf, 2023) - License: Unicode Files extracted from upstream source: @@ -280,10 +280,11 @@ Files generated from upstream source: https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/buildtool.md for instructions). -- Step 1: Build ICU with default options - `./runConfigureICU {PLATFORM} && make`. -- Step 2: Reconfigure ICU with custom data config - `ICU_DATA_FILTER_FILE={GODOT_SOURCE}/thirdparty/icu4c/godot_data.json ./runConfigureICU {PLATFORM} --with-data-packaging=common`. -- Step 3: Delete `data/out` folder and rebuild data - `cd data && rm -rf ./out && make`. -- Step 4: Copy `source/data/out/icudt73l.dat` to the `{GODOT_SOURCE}/thirdparty/icu4c/icudt73l.dat`. +- Step 1: Download and extract both `icu4c-{version}-src.tgz` and `icu4c-{version}-data.zip` (replace `data` subfolder from the main source archive). +- Step 2: Build ICU with default options - `./runConfigureICU {PLATFORM} && make`. +- Step 3: Reconfigure ICU with custom data config - `ICU_DATA_FILTER_FILE={GODOT_SOURCE}/thirdparty/icu4c/godot_data.json ./runConfigureICU {PLATFORM} --with-data-packaging=common`. +- Step 4: Delete `data/out` folder and rebuild data - `cd data && rm -rf ./out && make`. +- Step 5: Copy `source/data/out/icudt73l.dat` to the `{GODOT_SOURCE}/thirdparty/icu4c/icudt73l.dat`. ## jpeg-compressor @@ -582,7 +583,7 @@ Patch files are provided in `oidn/patches/`. ## openxr - Upstream: https://github.com/KhronosGroup/OpenXR-SDK -- Version: 1.0.26 (e2da9ce83a4388c9622da328bf48548471261290, 2022) +- Version: 1.0.28 (f5beb0131f1bea8701ace744d1b50df9049bf331, 2023) - License: Apache 2.0 Files extracted from upstream source: @@ -600,7 +601,8 @@ Exclude: - src/external/android-jni-wrappers and src/external/jnipp (not used yet) - All CMake stuff: cmake/, CMakeLists.txt and *.cmake - All Gradle stuff: *gradle*, AndroidManifest.xml -- All following files (and their .license files): *.{def,in,json,map,pom,rc} +- All following files (and their .license files): *.{def,expsym,in,json,map,pom,rc,txt} +- All dotfiles ## pcre2 @@ -639,13 +641,13 @@ Files extracted from upstream source: For 2D in `rvo2_2d` folder - Upstream: https://github.com/snape/RVO2 -- Version: git (5961f05ed310f3a5e902aa70ad54e010ba6dcdfd, 2022) +- Version: git (f7c5380235f6c9ac8d19cbf71fc94e2d4758b0a3, 2021) - License: Apache 2.0 For 3D in `rvo2_3d` folder - Upstream: https://github.com/snape/RVO2-3D -- Version: git (8be355eb84dc763267b5acf7070d6d623d752e51, 2022) +- Version: git (bfc048670a4e85066e86a1f923d8ea92e3add3b2, 2021) - License: Apache 2.0 Files extracted from upstream source: diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h index 77f8004b80..5232f8a869 100644 --- a/thirdparty/enet/enet/enet.h +++ b/thirdparty/enet/enet/enet.h @@ -68,7 +68,8 @@ typedef enum _ENetSocketOption ENET_SOCKOPT_RCVTIMEO = 6, ENET_SOCKOPT_SNDTIMEO = 7, ENET_SOCKOPT_ERROR = 8, - ENET_SOCKOPT_NODELAY = 9 + ENET_SOCKOPT_NODELAY = 9, + ENET_SOCKOPT_TTL = 10 } ENetSocketOption; typedef enum _ENetSocketShutdown @@ -179,7 +180,7 @@ typedef struct _ENetOutgoingCommand enet_uint16 unreliableSequenceNumber; enet_uint32 sentTime; enet_uint32 roundTripTimeout; - enet_uint32 roundTripTimeoutLimit; + enet_uint32 queueTime; enet_uint32 fragmentOffset; enet_uint16 fragmentLength; enet_uint16 sendAttempts; @@ -222,7 +223,7 @@ enum ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024, ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024, ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000, - ENET_HOST_DEFAULT_MTU = 1400, + ENET_HOST_DEFAULT_MTU = 1392, ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024, ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024, @@ -262,7 +263,8 @@ typedef struct _ENetChannel typedef enum _ENetPeerFlag { - ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0) + ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0), + ENET_PEER_FLAG_CONTINUE_SENDING = (1 << 1) } ENetPeerFlag; /** @@ -322,7 +324,7 @@ typedef struct _ENetPeer enet_uint16 outgoingReliableSequenceNumber; ENetList acknowledgements; ENetList sentReliableCommands; - ENetList sentUnreliableCommands; + ENetList outgoingSendReliableCommands; ENetList outgoingCommands; ENetList dispatchedCommands; enet_uint16 flags; @@ -385,7 +387,7 @@ typedef struct _ENetHost size_t channelLimit; /**< maximum number of channels allowed for connected peers */ enet_uint32 serviceTime; ENetList dispatchQueue; - int continueSending; + enet_uint32 totalQueued; size_t packetSize; enet_uint16 headerFlags; ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; @@ -585,6 +587,7 @@ ENET_API void enet_host_channel_limit (ENetHost *, size_t); ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32); extern void enet_host_bandwidth_throttle (ENetHost *); extern enet_uint32 enet_host_random_seed (void); +extern enet_uint32 enet_host_random (ENetHost *); ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *); ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID); @@ -598,6 +601,7 @@ ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32 ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); extern int enet_peer_throttle (ENetPeer *, enet_uint32); extern void enet_peer_reset_queues (ENetPeer *); +extern int enet_peer_has_outgoing_commands (ENetPeer *); extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *); extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, const void *, size_t, enet_uint32, enet_uint32); diff --git a/thirdparty/enet/godot.cpp b/thirdparty/enet/godot.cpp index 2cbfe59fc6..9ce126a475 100644 --- a/thirdparty/enet/godot.cpp +++ b/thirdparty/enet/godot.cpp @@ -535,6 +535,10 @@ int enet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buf if (err == ERR_BUSY) { return 0; } + if (err == ERR_OUT_OF_MEMORY) { + // A packet above the ENET_PROTOCOL_MAXIMUM_MTU was received. + return -2; + } if (err != OK) { return -1; diff --git a/thirdparty/enet/host.c b/thirdparty/enet/host.c index 21ab27e247..adb3533cf1 100644 --- a/thirdparty/enet/host.c +++ b/thirdparty/enet/host.c @@ -96,6 +96,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL host -> totalSentPackets = 0; host -> totalReceivedData = 0; host -> totalReceivedPackets = 0; + host -> totalQueued = 0; host -> connectedPeers = 0; host -> bandwidthLimitedPeers = 0; @@ -123,8 +124,8 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL enet_list_clear (& currentPeer -> acknowledgements); enet_list_clear (& currentPeer -> sentReliableCommands); - enet_list_clear (& currentPeer -> sentUnreliableCommands); enet_list_clear (& currentPeer -> outgoingCommands); + enet_list_clear (& currentPeer -> outgoingSendReliableCommands); enet_list_clear (& currentPeer -> dispatchedCommands); enet_peer_reset (currentPeer); @@ -160,6 +161,16 @@ enet_host_destroy (ENetHost * host) enet_free (host); } +enet_uint32 +enet_host_random (ENetHost * host) +{ + /* Mulberry32 by Tommy Ettinger */ + enet_uint32 n = (host -> randomSeed += 0x6D2B79F5U); + n = (n ^ (n >> 15)) * (n | 1U); + n ^= n + (n ^ (n >> 7)) * (n | 61U); + return n ^ (n >> 14); +} + /** Initiates a connection to a foreign host. @param host host seeking the connection @param address destination for the connection @@ -199,7 +210,8 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC currentPeer -> channelCount = channelCount; currentPeer -> state = ENET_PEER_STATE_CONNECTING; currentPeer -> address = * address; - currentPeer -> connectID = ++ host -> randomSeed; + currentPeer -> connectID = enet_host_random (host); + currentPeer -> mtu = host -> mtu; if (host -> outgoingBandwidth == 0) currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; diff --git a/thirdparty/enet/packet.c b/thirdparty/enet/packet.c index 5fa78b28ae..d51c640404 100644 --- a/thirdparty/enet/packet.c +++ b/thirdparty/enet/packet.c @@ -98,53 +98,46 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength) return 0; } -static int initializedCRC32 = 0; -static enet_uint32 crcTable [256]; - -static enet_uint32 -reflect_crc (int val, int bits) +static const enet_uint32 crcTable [256] = { - int result = 0, bit; - - for (bit = 0; bit < bits; bit ++) - { - if(val & 1) result |= 1 << (bits - 1 - bit); - val >>= 1; - } - - return result; -} - -static void -initialize_crc32 (void) -{ - int byte; - - for (byte = 0; byte < 256; ++ byte) - { - enet_uint32 crc = reflect_crc (byte, 8) << 24; - int offset; + 0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x5005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0xBDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; - for(offset = 0; offset < 8; ++ offset) - { - if (crc & 0x80000000) - crc = (crc << 1) ^ 0x04c11db7; - else - crc <<= 1; - } - - crcTable [byte] = reflect_crc (crc, 32); - } - - initializedCRC32 = 1; -} - enet_uint32 enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) { enet_uint32 crc = 0xFFFFFFFF; - - if (! initializedCRC32) initialize_crc32 (); while (bufferCount -- > 0) { @@ -153,7 +146,7 @@ enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) while (data < dataEnd) { - crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++]; + crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++]; } ++ buffers; diff --git a/thirdparty/enet/peer.c b/thirdparty/enet/peer.c index 9370ef4be1..a7ac012079 100644 --- a/thirdparty/enet/peer.c +++ b/thirdparty/enet/peer.c @@ -90,6 +90,13 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt) } /** Queues a packet to be sent. + + On success, ENet will assume ownership of the packet, and so enet_packet_destroy + should not be called on it thereafter. On failure, the caller still must destroy + the packet on its own as ENet has not queued the packet. The caller can also + check the packet's referenceCount field after sending to check if ENet queued + the packet and thus incremented the referenceCount. + @param peer destination for the packet @param channelID channel on which to send @param packet packet to send @@ -99,7 +106,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt) int enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) { - ENetChannel * channel = & peer -> channels [channelID]; + ENetChannel * channel; ENetProtocol command; size_t fragmentLength; @@ -108,6 +115,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) packet -> dataLength > peer -> host -> maximumPacketSize) return -1; + channel = & peer -> channels [channelID]; fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment); if (peer -> host -> checksum != NULL) fragmentLength -= sizeof(enet_uint32); @@ -320,8 +328,8 @@ enet_peer_reset_queues (ENetPeer * peer) enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements))); enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands); - enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands); enet_peer_reset_outgoing_commands (& peer -> outgoingCommands); + enet_peer_reset_outgoing_commands (& peer -> outgoingSendReliableCommands); enet_peer_reset_incoming_commands (& peer -> dispatchedCommands); if (peer -> channels != NULL && peer -> channelCount > 0) @@ -563,6 +571,17 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data) } } +int +enet_peer_has_outgoing_commands (ENetPeer * peer) +{ + if (enet_list_empty (& peer -> outgoingCommands) && + enet_list_empty (& peer -> outgoingSendReliableCommands) && + enet_list_empty (& peer -> sentReliableCommands)) + return 0; + + return 1; +} + /** Request a disconnection from a peer, but only after all queued outgoing packets are sent. @param peer peer to request a disconnection @param data data describing the disconnection @@ -573,8 +592,7 @@ void enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data) { if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && - ! (enet_list_empty (& peer -> outgoingCommands) && - enet_list_empty (& peer -> sentReliableCommands))) + enet_peer_has_outgoing_commands (peer)) { peer -> state = ENET_PEER_STATE_DISCONNECT_LATER; peer -> eventData = data; @@ -618,8 +636,6 @@ enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, void enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand) { - ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID]; - peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength; if (outgoingCommand -> command.header.channelID == 0xFF) @@ -630,36 +646,40 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin outgoingCommand -> unreliableSequenceNumber = 0; } else - if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) { - ++ channel -> outgoingReliableSequenceNumber; - channel -> outgoingUnreliableSequenceNumber = 0; + ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID]; - outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; - outgoingCommand -> unreliableSequenceNumber = 0; - } - else - if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED) - { - ++ peer -> outgoingUnsequencedGroup; + if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) + { + ++ channel -> outgoingReliableSequenceNumber; + channel -> outgoingUnreliableSequenceNumber = 0; - outgoingCommand -> reliableSequenceNumber = 0; - outgoingCommand -> unreliableSequenceNumber = 0; - } - else - { - if (outgoingCommand -> fragmentOffset == 0) - ++ channel -> outgoingUnreliableSequenceNumber; - - outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; - outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; + outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; + outgoingCommand -> unreliableSequenceNumber = 0; + } + else + if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED) + { + ++ peer -> outgoingUnsequencedGroup; + + outgoingCommand -> reliableSequenceNumber = 0; + outgoingCommand -> unreliableSequenceNumber = 0; + } + else + { + if (outgoingCommand -> fragmentOffset == 0) + ++ channel -> outgoingUnreliableSequenceNumber; + + outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; + outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; + } } - + outgoingCommand -> sendAttempts = 0; outgoingCommand -> sentTime = 0; outgoingCommand -> roundTripTimeout = 0; - outgoingCommand -> roundTripTimeoutLimit = 0; outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber); + outgoingCommand -> queueTime = ++ peer -> host -> totalQueued; switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) { @@ -670,12 +690,16 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: outgoingCommand -> command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup); break; - + default: break; } - enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand); + if ((outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0 && + outgoingCommand -> packet != NULL) + enet_list_insert (enet_list_end (& peer -> outgoingSendReliableCommands), outgoingCommand); + else + enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand); } ENetOutgoingCommand * diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c index d7fe80f117..af307af7e5 100644 --- a/thirdparty/enet/protocol.c +++ b/thirdparty/enet/protocol.c @@ -9,7 +9,7 @@ #include "enet/time.h" #include "enet/enet.h" -static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = +static const size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = { 0, sizeof (ENetProtocolAcknowledge), @@ -159,16 +159,16 @@ enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * e } static void -enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) +enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer, ENetList * sentUnreliableCommands) { ENetOutgoingCommand * outgoingCommand; - if (enet_list_empty (& peer -> sentUnreliableCommands)) + if (enet_list_empty (sentUnreliableCommands)) return; do { - outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands); + outgoingCommand = (ENetOutgoingCommand *) enet_list_front (sentUnreliableCommands); enet_list_remove (& outgoingCommand -> outgoingCommandList); @@ -185,14 +185,38 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) } enet_free (outgoingCommand); - } while (! enet_list_empty (& peer -> sentUnreliableCommands)); + } while (! enet_list_empty (sentUnreliableCommands)); if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && - enet_list_empty (& peer -> outgoingCommands) && - enet_list_empty (& peer -> sentReliableCommands)) + ! enet_peer_has_outgoing_commands (peer)) enet_peer_disconnect (peer, peer -> eventData); } +static ENetOutgoingCommand * +enet_protocol_find_sent_reliable_command (ENetList * list, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) +{ + ENetListIterator currentCommand; + + for (currentCommand = enet_list_begin (list); + currentCommand != enet_list_end (list); + currentCommand = enet_list_next (currentCommand)) + { + ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)) + continue; + + if (outgoingCommand -> sendAttempts < 1) + break; + + if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && + outgoingCommand -> command.header.channelID == channelID) + return outgoingCommand; + } + + return NULL; +} + static ENetProtocolCommand enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) { @@ -214,24 +238,9 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) { - for (currentCommand = enet_list_begin (& peer -> outgoingCommands); - currentCommand != enet_list_end (& peer -> outgoingCommands); - currentCommand = enet_list_next (currentCommand)) - { - outgoingCommand = (ENetOutgoingCommand *) currentCommand; - - if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)) - continue; - - if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE; - - if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && - outgoingCommand -> command.header.channelID == channelID) - break; - } - - if (currentCommand == enet_list_end (& peer -> outgoingCommands)) - return ENET_PROTOCOL_COMMAND_NONE; + outgoingCommand = enet_protocol_find_sent_reliable_command (& peer -> outgoingCommands, reliableSequenceNumber, channelID); + if (outgoingCommand == NULL) + outgoingCommand = enet_protocol_find_sent_reliable_command (& peer -> outgoingSendReliableCommands, reliableSequenceNumber, channelID); wasSent = 0; } @@ -331,6 +340,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; peer -> connectID = command -> connect.connectID; peer -> address = host -> receivedAddress; + peer -> mtu = host -> mtu; peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); @@ -375,7 +385,8 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) mtu = ENET_PROTOCOL_MAXIMUM_MTU; - peer -> mtu = mtu; + if (mtu < peer -> mtu) + peer -> mtu = mtu; if (host -> outgoingBandwidth == 0 && peer -> incomingBandwidth == 0) @@ -542,7 +553,8 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); * currentData += fragmentLength; - if (fragmentLength > host -> maximumPacketSize || + if (fragmentLength <= 0 || + fragmentLength > host -> maximumPacketSize || * currentData < host -> receivedData || * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; @@ -566,6 +578,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || fragmentNumber >= fragmentCount || totalLength > host -> maximumPacketSize || + totalLength < fragmentCount || fragmentOffset >= totalLength || fragmentLength > totalLength - fragmentOffset) return -1; @@ -921,8 +934,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * break; case ENET_PEER_STATE_DISCONNECT_LATER: - if (enet_list_empty (& peer -> outgoingCommands) && - enet_list_empty (& peer -> sentReliableCommands)) + if (! enet_peer_has_outgoing_commands (peer)) enet_peer_disconnect (peer, peer -> eventData); break; @@ -1230,6 +1242,9 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) & buffer, 1); + if (receivedLength == -2) + continue; + if (receivedLength < 0) return -1; @@ -1293,7 +1308,7 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge)) { - host -> continueSending = 1; + peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING; break; } @@ -1333,10 +1348,11 @@ static int enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event) { ENetOutgoingCommand * outgoingCommand; - ENetListIterator currentCommand, insertPosition; + ENetListIterator currentCommand, insertPosition, insertSendReliablePosition; currentCommand = enet_list_begin (& peer -> sentReliableCommands); insertPosition = enet_list_begin (& peer -> outgoingCommands); + insertSendReliablePosition = enet_list_begin (& peer -> outgoingSendReliableCommands); while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) { @@ -1353,7 +1369,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even if (peer -> earliestTimeout != 0 && (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum || - (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit && + ((1 << (outgoingCommand -> sendAttempts - 1)) >= peer -> timeoutLimit && ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum))) { enet_protocol_notify_disconnect (host, peer, event); @@ -1361,14 +1377,18 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even return 1; } - if (outgoingCommand -> packet != NULL) - peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; - ++ peer -> packetsLost; outgoingCommand -> roundTripTimeout *= 2; - enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); + if (outgoingCommand -> packet != NULL) + { + peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; + + enet_list_insert (insertSendReliablePosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); + } + else + enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && ! enet_list_empty (& peer -> sentReliableCommands)) @@ -1383,22 +1403,41 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even } static int -enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer) +enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer, ENetList * sentUnreliableCommands) { ENetProtocol * command = & host -> commands [host -> commandCount]; ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; ENetOutgoingCommand * outgoingCommand; - ENetListIterator currentCommand; - ENetChannel *channel; - enet_uint16 reliableWindow; + ENetListIterator currentCommand, currentSendReliableCommand; + ENetChannel *channel = NULL; + enet_uint16 reliableWindow = 0; size_t commandSize; - int windowExceeded = 0, windowWrap = 0, canPing = 1; + int windowWrap = 0, canPing = 1; currentCommand = enet_list_begin (& peer -> outgoingCommands); - - while (currentCommand != enet_list_end (& peer -> outgoingCommands)) + currentSendReliableCommand = enet_list_begin (& peer -> outgoingSendReliableCommands); + + for (;;) { - outgoingCommand = (ENetOutgoingCommand *) currentCommand; + if (currentCommand != enet_list_end (& peer -> outgoingCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands) && + ENET_TIME_LESS (((ENetOutgoingCommand *) currentSendReliableCommand) -> queueTime, outgoingCommand -> queueTime)) + goto useSendReliableCommand; + + currentCommand = enet_list_next (currentCommand); + } + else + if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands)) + { + useSendReliableCommand: + outgoingCommand = (ENetOutgoingCommand *) currentSendReliableCommand; + currentSendReliableCommand = enet_list_next (currentSendReliableCommand); + } + else + break; if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) { @@ -1406,33 +1445,29 @@ enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer) reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; if (channel != NULL) { - if (! windowWrap && - outgoingCommand -> sendAttempts < 1 && + if (windowWrap) + continue; + else + if (outgoingCommand -> sendAttempts < 1 && ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || channel -> usedReliableWindows & ((((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) << reliableWindow) | (((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow))))) - windowWrap = 1; - if (windowWrap) { - currentCommand = enet_list_next (currentCommand); - + windowWrap = 1; + currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands); + continue; } } - + if (outgoingCommand -> packet != NULL) { - if (! windowExceeded) - { - enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; - - if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) - windowExceeded = 1; - } - if (windowExceeded) + enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; + + if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) { - currentCommand = enet_list_next (currentCommand); + currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands); continue; } @@ -1448,13 +1483,11 @@ enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer) (outgoingCommand -> packet != NULL && (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))) { - host -> continueSending = 1; - + peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING; + break; } - currentCommand = enet_list_next (currentCommand); - if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) { if (channel != NULL && outgoingCommand -> sendAttempts < 1) @@ -1466,10 +1499,7 @@ enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer) ++ outgoingCommand -> sendAttempts; if (outgoingCommand -> roundTripTimeout == 0) - { - outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; - outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout; - } + outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; if (enet_list_empty (& peer -> sentReliableCommands)) peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout; @@ -1522,7 +1552,7 @@ enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer) enet_list_remove (& outgoingCommand -> outgoingCommandList); if (outgoingCommand -> packet != NULL) - enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); + enet_list_insert (enet_list_end (sentUnreliableCommands), outgoingCommand); } buffer -> data = command; @@ -1555,9 +1585,8 @@ enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer) host -> bufferCount = buffer - host -> buffers; if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && - enet_list_empty (& peer -> outgoingCommands) && - enet_list_empty (& peer -> sentReliableCommands) && - enet_list_empty (& peer -> sentUnreliableCommands)) + ! enet_peer_has_outgoing_commands (peer) && + enet_list_empty (sentUnreliableCommands)) enet_peer_disconnect (peer, peer -> eventData); return canPing; @@ -1568,22 +1597,24 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch { enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)]; ENetProtocolHeader * header = (ENetProtocolHeader *) headerData; - ENetPeer * currentPeer; - int sentLength; + int sentLength = 0; size_t shouldCompress = 0; - - host -> continueSending = 1; + ENetList sentUnreliableCommands; - while (host -> continueSending) - for (host -> continueSending = 0, - currentPeer = host -> peers; + enet_list_clear (& sentUnreliableCommands); + + for (int sendPass = 0, continueSending = 0; sendPass <= continueSending; ++ sendPass) + for (ENetPeer * currentPeer = host -> peers; currentPeer < & host -> peers [host -> peerCount]; ++ currentPeer) { if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED || - currentPeer -> state == ENET_PEER_STATE_ZOMBIE) + currentPeer -> state == ENET_PEER_STATE_ZOMBIE || + (sendPass > 0 && ! (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING))) continue; + currentPeer -> flags &= ~ ENET_PEER_FLAG_CONTINUE_SENDING; + host -> headerFlags = 0; host -> commandCount = 0; host -> bufferCount = 1; @@ -1600,21 +1631,22 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) return 1; else - continue; + goto nextPeer; } - if ((enet_list_empty (& currentPeer -> outgoingCommands) || - enet_protocol_check_outgoing_commands (host, currentPeer)) && + if (((enet_list_empty (& currentPeer -> outgoingCommands) && + enet_list_empty (& currentPeer -> outgoingSendReliableCommands)) || + enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands)) && enet_list_empty (& currentPeer -> sentReliableCommands) && ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) { enet_peer_ping (currentPeer); - enet_protocol_check_outgoing_commands (host, currentPeer); + enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands); } if (host -> commandCount == 0) - continue; + goto nextPeer; if (currentPeer -> packetLossEpoch == 0) currentPeer -> packetLossEpoch = host -> serviceTime; @@ -1625,7 +1657,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; #ifdef ENET_DEBUG - printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); + printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingCommands) + enet_list_size (& currentPeer -> outgoingSendReliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); #endif currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4; @@ -1687,13 +1719,17 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount); - enet_protocol_remove_sent_unreliable_commands (currentPeer); + enet_protocol_remove_sent_unreliable_commands (currentPeer, & sentUnreliableCommands); if (sentLength < 0) return -1; host -> totalSentData += sentLength; host -> totalSentPackets ++; + + nextPeer: + if (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING) + continueSending = sendPass + 1; } return 0; diff --git a/thirdparty/freetype/include/freetype/config/ftoption.h b/thirdparty/freetype/include/freetype/config/ftoption.h index 9e03e1783b..1976b33af9 100644 --- a/thirdparty/freetype/include/freetype/config/ftoption.h +++ b/thirdparty/freetype/include/freetype/config/ftoption.h @@ -661,36 +661,12 @@ FT_BEGIN_HEADER * not) instructions in a certain way so that all TrueType fonts look like * they do in a Windows ClearType (DirectWrite) environment. See [1] for a * technical overview on what this means. See `ttinterp.h` for more - * details on the LEAN option. + * details on this option. * - * There are three possible values. - * - * Value 1: - * This value is associated with the 'Infinality' moniker, contributed by - * an individual nicknamed Infinality with the goal of making TrueType - * fonts render better than on Windows. A high amount of configurability - * and flexibility, down to rules for single glyphs in fonts, but also - * very slow. Its experimental and slow nature and the original - * developer losing interest meant that this option was never enabled in - * default builds. - * - * The corresponding interpreter version is v38. - * - * Value 2: - * The new default mode for the TrueType driver. The Infinality code - * base was stripped to the bare minimum and all configurability removed - * in the name of speed and simplicity. The configurability was mainly - * aimed at legacy fonts like 'Arial', 'Times New Roman', or 'Courier'. - * Legacy fonts are fonts that modify vertical stems to achieve clean - * black-and-white bitmaps. The new mode focuses on applying a minimal - * set of rules to all fonts indiscriminately so that modern and web - * fonts render well while legacy fonts render okay. - * - * The corresponding interpreter version is v40. - * - * Value 3: - * Compile both, making both v38 and v40 available (the latter is the - * default). + * The new default mode focuses on applying a minimal set of rules to all + * fonts indiscriminately so that modern and web fonts render well while + * legacy fonts render okay. The corresponding interpreter version is v40. + * The so-called Infinality mode (v38) is no longer available in FreeType. * * By undefining these, you get rendering behavior like on Windows without * ClearType, i.e., Windows XP without ClearType enabled and Win9x @@ -705,9 +681,7 @@ FT_BEGIN_HEADER * [1] * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ -#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ +#define TT_CONFIG_OPTION_SUBPIXEL_HINTING /************************************************************************** @@ -977,22 +951,15 @@ FT_BEGIN_HEADER /* - * The next three macros are defined if native TrueType hinting is + * The next two macros are defined if native TrueType hinting is * requested by the definitions above. Don't change this. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER - #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 -#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY -#endif - -#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 #define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #endif #endif -#endif /* diff --git a/thirdparty/freetype/include/freetype/config/ftstdlib.h b/thirdparty/freetype/include/freetype/config/ftstdlib.h index 3c9d2ae59a..f65148a902 100644 --- a/thirdparty/freetype/include/freetype/config/ftstdlib.h +++ b/thirdparty/freetype/include/freetype/config/ftstdlib.h @@ -111,13 +111,13 @@ #include <stdio.h> -#define FT_FILE FILE -#define ft_fclose fclose -#define ft_fopen fopen -#define ft_fread fread -#define ft_fseek fseek -#define ft_ftell ftell -#define ft_sprintf sprintf +#define FT_FILE FILE +#define ft_fclose fclose +#define ft_fopen fopen +#define ft_fread fread +#define ft_fseek fseek +#define ft_ftell ftell +#define ft_snprintf snprintf /************************************************************************** diff --git a/thirdparty/freetype/include/freetype/freetype.h b/thirdparty/freetype/include/freetype/freetype.h index efff74fe39..4a074a4449 100644 --- a/thirdparty/freetype/include/freetype/freetype.h +++ b/thirdparty/freetype/include/freetype/freetype.h @@ -102,61 +102,25 @@ FT_BEGIN_HEADER */ - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* B A S I C T Y P E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - /************************************************************************** * * @section: - * base_interface + * font_testing_macros * * @title: - * Base Interface + * Font Testing Macros * * @abstract: - * The FreeType~2 base font interface. + * Macros to test various properties of fonts. * * @description: - * This section describes the most important public high-level API - * functions of FreeType~2. + * Macros to test the most important font properties. * - * @order: - * FT_Library - * FT_Face - * FT_Size - * FT_GlyphSlot - * FT_CharMap - * FT_Encoding - * FT_ENC_TAG - * - * FT_FaceRec - * - * FT_FACE_FLAG_SCALABLE - * FT_FACE_FLAG_FIXED_SIZES - * FT_FACE_FLAG_FIXED_WIDTH - * FT_FACE_FLAG_HORIZONTAL - * FT_FACE_FLAG_VERTICAL - * FT_FACE_FLAG_COLOR - * FT_FACE_FLAG_SFNT - * FT_FACE_FLAG_CID_KEYED - * FT_FACE_FLAG_TRICKY - * FT_FACE_FLAG_KERNING - * FT_FACE_FLAG_MULTIPLE_MASTERS - * FT_FACE_FLAG_VARIATION - * FT_FACE_FLAG_GLYPH_NAMES - * FT_FACE_FLAG_EXTERNAL_STREAM - * FT_FACE_FLAG_HINTER - * FT_FACE_FLAG_SVG - * FT_FACE_FLAG_SBIX - * FT_FACE_FLAG_SBIX_OVERLAY + * It is recommended to use these high-level macros instead of directly + * testing the corresponding flags, which are scattered over various + * structures. * + * @order: * FT_HAS_HORIZONTAL * FT_HAS_VERTICAL * FT_HAS_KERNING @@ -176,21 +140,59 @@ FT_BEGIN_HEADER * FT_IS_NAMED_INSTANCE * FT_IS_VARIATION * - * FT_STYLE_FLAG_BOLD - * FT_STYLE_FLAG_ITALIC + */ + + + /************************************************************************** + * + * @section: + * library_setup * - * FT_SizeRec - * FT_Size_Metrics + * @title: + * Library Setup * - * FT_GlyphSlotRec - * FT_Glyph_Metrics - * FT_SubGlyph + * @abstract: + * Functions to start and end the usage of the FreeType library. * - * FT_Bitmap_Size + * @description: + * Functions to start and end the usage of the FreeType library. + * + * Note that @FT_Library_Version and @FREETYPE_XXX are of limited use + * because even a new release of FreeType with only documentation + * changes increases the version number. * + * @order: + * FT_Library * FT_Init_FreeType * FT_Done_FreeType * + * FT_Library_Version + * FREETYPE_XXX + * + */ + + + /************************************************************************** + * + * @section: + * face_creation + * + * @title: + * Face Creation + * + * @abstract: + * Functions to manage fonts. + * + * @description: + * The functions and structures collected in this section operate on + * fonts globally. + * + * @order: + * FT_Face + * FT_FaceRec + * FT_FACE_FLAG_XXX + * FT_STYLE_FLAG_XXX + * * FT_New_Face * FT_Done_Face * FT_Reference_Face @@ -198,10 +200,36 @@ FT_BEGIN_HEADER * FT_Face_Properties * FT_Open_Face * FT_Open_Args + * FT_OPEN_XXX * FT_Parameter * FT_Attach_File * FT_Attach_Stream * + */ + + + /************************************************************************** + * + * @section: + * sizing_and_scaling + * + * @title: + * Sizing and Scaling + * + * @abstract: + * Functions to manage font sizes. + * + * @description: + * The functions and structures collected in this section are related to + * selecting and manipulating the size of a font globally. + * + * @order: + * FT_Size + * FT_SizeRec + * FT_Size_Metrics + * + * FT_Bitmap_Size + * * FT_Set_Char_Size * FT_Set_Pixel_Sizes * FT_Request_Size @@ -209,44 +237,37 @@ FT_BEGIN_HEADER * FT_Size_Request_Type * FT_Size_RequestRec * FT_Size_Request + * * FT_Set_Transform * FT_Get_Transform - * FT_Load_Glyph - * FT_Get_Char_Index - * FT_Get_First_Char - * FT_Get_Next_Char - * FT_Load_Char * - * FT_OPEN_MEMORY - * FT_OPEN_STREAM - * FT_OPEN_PATHNAME - * FT_OPEN_DRIVER - * FT_OPEN_PARAMS - * - * FT_LOAD_DEFAULT - * FT_LOAD_RENDER - * FT_LOAD_MONOCHROME - * FT_LOAD_LINEAR_DESIGN - * FT_LOAD_NO_SCALE - * FT_LOAD_NO_HINTING - * FT_LOAD_NO_BITMAP - * FT_LOAD_SBITS_ONLY - * FT_LOAD_NO_AUTOHINT - * FT_LOAD_COLOR - * - * FT_LOAD_VERTICAL_LAYOUT - * FT_LOAD_IGNORE_TRANSFORM - * FT_LOAD_FORCE_AUTOHINT - * FT_LOAD_NO_RECURSE - * FT_LOAD_PEDANTIC - * - * FT_LOAD_TARGET_NORMAL - * FT_LOAD_TARGET_LIGHT - * FT_LOAD_TARGET_MONO - * FT_LOAD_TARGET_LCD - * FT_LOAD_TARGET_LCD_V + */ + + + /************************************************************************** + * + * @section: + * glyph_retrieval + * + * @title: + * Glyph Retrieval + * + * @abstract: + * Functions to manage glyphs. + * + * @description: + * The functions and structures collected in this section operate on + * single glyphs, of which @FT_Load_Glyph is most important. * + * @order: + * FT_GlyphSlot + * FT_GlyphSlotRec + * FT_Glyph_Metrics + * + * FT_Load_Glyph + * FT_LOAD_XXX * FT_LOAD_TARGET_MODE + * FT_LOAD_TARGET_XXX * * FT_Render_Glyph * FT_Render_Mode @@ -254,34 +275,121 @@ FT_BEGIN_HEADER * FT_Kerning_Mode * FT_Get_Track_Kerning * + */ + + + /************************************************************************** + * + * @section: + * character_mapping + * + * @title: + * Character Mapping + * + * @abstract: + * Functions to manage character-to-glyph maps. + * + * @description: + * This section holds functions and structures that are related to + * mapping character input codes to glyph indices. + * + * Note that for many scripts the simplistic approach used by FreeType + * of mapping a single character to a single glyph is not valid or + * possible! In general, a higher-level library like HarfBuzz or ICU + * should be used for handling text strings. + * + * @order: + * FT_CharMap * FT_CharMapRec + * FT_Encoding + * FT_ENC_TAG + * * FT_Select_Charmap * FT_Set_Charmap * FT_Get_Charmap_Index * + * FT_Get_Char_Index + * FT_Get_First_Char + * FT_Get_Next_Char + * FT_Load_Char + * + */ + + + /************************************************************************** + * + * @section: + * information_retrieval + * + * @title: + * Information Retrieval + * + * @abstract: + * Functions to retrieve font and glyph information. + * + * @description: + * Functions to retrieve font and glyph information. Only some very + * basic data is covered; see also the chapter on the format-specific + * API for more. + * + * + * @order: * FT_Get_Name_Index * FT_Get_Glyph_Name * FT_Get_Postscript_Name * FT_Get_FSType_Flags + * FT_FSTYPE_XXX * FT_Get_SubGlyph_Info + * FT_SUBGLYPH_FLAG_XXX + * + */ + + + /************************************************************************** + * + * @section: + * other_api_data + * + * @title: + * Other API Data + * + * @abstract: + * Other structures, enumerations, and macros. * + * @description: + * Other structures, enumerations, and macros. Deprecated functions are + * also listed here. + * + * @order: * FT_Face_Internal * FT_Size_Internal * FT_Slot_Internal * - * FT_FACE_FLAG_XXX - * FT_STYLE_FLAG_XXX - * FT_OPEN_XXX - * FT_LOAD_XXX - * FT_LOAD_TARGET_XXX - * FT_SUBGLYPH_FLAG_XXX - * FT_FSTYPE_XXX + * FT_SubGlyph * * FT_HAS_FAST_GLYPHS + * FT_Face_CheckTrueTypePatents + * FT_Face_SetUnpatentedHinting * */ + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S I C T Y P E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************** + * + * @section: + * glyph_retrieval + * + */ + /************************************************************************** * * @struct: @@ -351,6 +459,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * sizing_and_scaling + * + */ + + /************************************************************************** + * * @struct: * FT_Bitmap_Size * @@ -411,6 +526,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * library_setup + * + */ + + /************************************************************************** + * * @type: * FT_Library * @@ -483,7 +605,7 @@ FT_BEGIN_HEADER /************************************************************************** * * @section: - * base_interface + * face_creation * */ @@ -521,6 +643,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * sizing_and_scaling + * + */ + + /************************************************************************** + * * @type: * FT_Size * @@ -553,6 +682,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * glyph_retrieval + * + */ + + /************************************************************************** + * * @type: * FT_GlyphSlot * @@ -572,6 +708,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * character_mapping + * + */ + + /************************************************************************** + * * @type: * FT_CharMap * @@ -879,6 +1022,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * other_api_data + * + */ + + /************************************************************************** + * * @type: * FT_Face_Internal * @@ -894,6 +1044,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * face_creation + * + */ + + /************************************************************************** + * * @struct: * FT_FaceRec * @@ -918,7 +1075,7 @@ FT_BEGIN_HEADER * If we have the third named instance of face~4, say, `face_index` is * set to 0x00030004. * - * Bit 31 is always zero (this is, `face_index` is always a positive + * Bit 31 is always zero (that is, `face_index` is always a positive * value). * * [Since 2.9] Changing the design coordinates with @@ -936,7 +1093,7 @@ FT_BEGIN_HEADER * * [Since 2.6.1] Bits 16-30 hold the number of named instances * available for the current face if we have a GX or OpenType variation - * (sub)font. Bit 31 is always zero (this is, `style_flags` is always + * (sub)font. Bit 31 is always zero (that is, `style_flags` is always * a positive value). Note that a variation font has always at least * one named instance, namely the default instance. * @@ -1002,7 +1159,7 @@ FT_BEGIN_HEADER * Note that the bounding box might be off by (at least) one pixel for * hinted fonts. See @FT_Size_Metrics for further discussion. * - * Note that the bounding box does not vary in OpenType variable fonts + * Note that the bounding box does not vary in OpenType variation fonts * and should only be used in relation to the default instance. * * units_per_EM :: @@ -1090,9 +1247,9 @@ FT_BEGIN_HEADER FT_Generic generic; - /*# The following member variables (down to `underline_thickness`) */ - /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ - /*# for bitmap fonts. */ + /* The following member variables (down to `underline_thickness`) */ + /* are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ + /* for bitmap fonts. */ FT_BBox bbox; FT_UShort units_per_EM; @@ -1110,7 +1267,7 @@ FT_BEGIN_HEADER FT_Size size; FT_CharMap charmap; - /*@private begin */ + /* private fields, internal to FreeType */ FT_Driver driver; FT_Memory memory; @@ -1123,8 +1280,6 @@ FT_BEGIN_HEADER FT_Face_Internal internal; - /*@private end */ - } FT_FaceRec; @@ -1207,13 +1362,13 @@ FT_BEGIN_HEADER * successfully; in all other cases you get an * `FT_Err_Invalid_Argument` error. * - * Note that CID-keyed fonts that are in an SFNT wrapper (this is, all + * Note that CID-keyed fonts that are in an SFNT wrapper (that is, all * OpenType/CFF fonts) don't have this flag set since the glyphs are * accessed in the normal way (using contiguous indices); the * 'CID-ness' isn't visible to the application. * * FT_FACE_FLAG_TRICKY :: - * The face is 'tricky', this is, it always needs the font format's + * The face is 'tricky', that is, it always needs the font format's * native hinting engine to get a reasonable result. A typical example * is the old Chinese font `mingli.ttf` (but not `mingliu.ttc`) that * uses TrueType bytecode instructions to move and scale all of its @@ -1235,8 +1390,8 @@ FT_BEGIN_HEADER * FT_FACE_FLAG_VARIATION :: * [Since 2.9] Set if the current face (or named instance) has been * altered with @FT_Set_MM_Design_Coordinates, - * @FT_Set_Var_Design_Coordinates, or @FT_Set_Var_Blend_Coordinates. - * This flag is unset by a call to @FT_Set_Named_Instance. + * @FT_Set_Var_Design_Coordinates, @FT_Set_Var_Blend_Coordinates, or + * @FT_Set_MM_WeightVector to select a non-default instance. * * FT_FACE_FLAG_SVG :: * [Since 2.12] The face has an 'SVG~' OpenType table. @@ -1274,6 +1429,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * font_testing_macros + * + */ + + /************************************************************************** + * * @macro: * FT_HAS_HORIZONTAL * @@ -1383,6 +1545,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * other_api_data + * + */ + + /************************************************************************** + * * @macro: * FT_HAS_FAST_GLYPHS * @@ -1395,6 +1564,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * font_testing_macros + * + */ + + /************************************************************************** + * * @macro: * FT_HAS_GLYPH_NAMES * @@ -1451,8 +1627,8 @@ FT_BEGIN_HEADER * * @description: * A macro that returns true whenever a face object has been altered by - * @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or - * @FT_Set_Var_Blend_Coordinates. + * @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, + * @FT_Set_Var_Blend_Coordinates, or @FT_Set_MM_WeightVector. * * @since: * 2.9 @@ -1630,6 +1806,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * face_creation + * + */ + + /************************************************************************** + * * @enum: * FT_STYLE_FLAG_XXX * @@ -1656,6 +1839,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * other_api_data + * + */ + + /************************************************************************** + * * @type: * FT_Size_Internal * @@ -1668,6 +1858,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * sizing_and_scaling + * + */ + + /************************************************************************** + * * @struct: * FT_Size_Metrics * @@ -1819,6 +2016,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * other_api_data + * + */ + + /************************************************************************** + * * @struct: * FT_SubGlyph * @@ -1850,6 +2054,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * glyph_retrieval + * + */ + + /************************************************************************** + * * @struct: * FT_GlyphSlotRec * @@ -2094,6 +2305,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * library_setup + * + */ + + /************************************************************************** + * * @function: * FT_Init_FreeType * @@ -2151,6 +2369,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * face_creation + * + */ + + /************************************************************************** + * * @enum: * FT_OPEN_XXX * @@ -2451,7 +2676,7 @@ FT_BEGIN_HEADER * Each new face object created with this function also owns a default * @FT_Size object, accessible as `face->size`. * - * One @FT_Library instance can have multiple face objects, this is, + * One @FT_Library instance can have multiple face objects, that is, * @FT_Open_Face and its siblings can be called multiple times using the * same `library` argument. * @@ -2652,6 +2877,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * sizing_and_scaling + * + */ + + /************************************************************************** + * * @function: * FT_Select_Size * @@ -2679,7 +2911,7 @@ FT_BEGIN_HEADER * silently uses outlines if there is no bitmap for a given glyph index. * * For GX and OpenType variation fonts, a bitmap strike makes sense only - * if the default instance is active (this is, no glyph variation takes + * if the default instance is active (that is, no glyph variation takes * place); otherwise, FreeType simply ignores bitmap strikes. The same * is true for all named instances that are different from the default * instance. @@ -2944,6 +3176,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * glyph_retrieval + * + */ + + /************************************************************************** + * * @function: * FT_Load_Glyph * @@ -2976,7 +3215,7 @@ FT_BEGIN_HEADER * glyph may be transformed. See @FT_Set_Transform for the details. * * For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument` is returned - * for invalid CID values (this is, for CID values that don't have a + * for invalid CID values (that is, for CID values that don't have a * corresponding glyph in the font). See the discussion of the * @FT_FACE_FLAG_CID_KEYED flag for more details. * @@ -2992,6 +3231,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * character_mapping + * + */ + + /************************************************************************** + * * @function: * FT_Load_Char * @@ -3035,6 +3281,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * glyph_retrieval + * + */ + + /************************************************************************** + * * @enum: * FT_LOAD_XXX * @@ -3172,10 +3425,11 @@ FT_BEGIN_HEADER * * [Since 2.12] If the glyph index maps to an entry in the face's * 'SVG~' table, load the associated SVG document from this table and - * set the `format` field of @FT_GlyphSlotRec to @FT_GLYPH_FORMAT_SVG. - * Note that FreeType itself can't render SVG documents; however, the - * library provides hooks to seamlessly integrate an external renderer. - * See sections @ot_svg_driver and @svg_fonts for more. + * set the `format` field of @FT_GlyphSlotRec to @FT_GLYPH_FORMAT_SVG + * ([since 2.13.1] provided @FT_LOAD_NO_SVG is not set). Note that + * FreeType itself can't render SVG documents; however, the library + * provides hooks to seamlessly integrate an external renderer. See + * sections @ot_svg_driver and @svg_fonts for more. * * [Since 2.10, experimental] If the glyph index maps to an entry in * the face's 'COLR' table with a 'CPAL' palette table (as defined in @@ -3189,6 +3443,9 @@ FT_BEGIN_HEADER * @FT_Palette_Select instead of setting @FT_LOAD_COLOR for rendering * so that the client application can handle blending by itself. * + * FT_LOAD_NO_SVG :: + * [Since 2.13.1] Ignore SVG glyph data when loading. + * * FT_LOAD_COMPUTE_METRICS :: * [Since 2.6.1] Compute glyph metrics from the glyph data, without the * use of bundled metrics tables (for example, the 'hdmx' table in @@ -3254,6 +3511,7 @@ FT_BEGIN_HEADER #define FT_LOAD_COLOR ( 1L << 20 ) #define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) #define FT_LOAD_BITMAP_METRICS_ONLY ( 1L << 22 ) +#define FT_LOAD_NO_SVG ( 1L << 24 ) /* */ @@ -3374,6 +3632,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * sizing_and_scaling + * + */ + + /************************************************************************** + * * @function: * FT_Set_Transform * @@ -3449,6 +3714,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * glyph_retrieval + * + */ + + /************************************************************************** + * * @enum: * FT_Render_Mode * @@ -3843,6 +4115,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * character_mapping + * + */ + + /************************************************************************** + * * @function: * FT_Select_Charmap * @@ -4059,6 +4338,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * face_creation + * + */ + + /************************************************************************** + * * @function: * FT_Face_Properties * @@ -4157,6 +4443,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * information_retrieval + * + */ + + /************************************************************************** + * * @function: * FT_Get_Name_Index * @@ -4266,9 +4559,10 @@ FT_BEGIN_HEADER * * [Since 2.9] Special PostScript names for named instances are only * returned if the named instance is set with @FT_Set_Named_Instance (and - * the font has corresponding entries in its 'fvar' table). If - * @FT_IS_VARIATION returns true, the algorithmically derived PostScript - * name is provided, not looking up special entries for named instances. + * the font has corresponding entries in its 'fvar' table or is the + * default named instance). If @FT_IS_VARIATION returns true, the + * algorithmically derived PostScript name is provided, not looking up + * special entries for named instances. */ FT_EXPORT( const char* ) FT_Get_Postscript_Name( FT_Face face ); @@ -4900,32 +5194,10 @@ FT_BEGIN_HEADER /************************************************************************** * * @section: - * version - * - * @title: - * FreeType Version - * - * @abstract: - * Functions and macros related to FreeType versions. - * - * @description: - * Note that those functions and macros are of limited use because even a - * new release of FreeType with only documentation changes increases the - * version number. - * - * @order: - * FT_Library_Version - * - * FREETYPE_MAJOR - * FREETYPE_MINOR - * FREETYPE_PATCH - * - * FT_Face_CheckTrueTypePatents - * FT_Face_SetUnpatentedHinting + * library_setup * */ - /************************************************************************** * * @enum: @@ -4950,7 +5222,7 @@ FT_BEGIN_HEADER */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 13 -#define FREETYPE_PATCH 0 +#define FREETYPE_PATCH 1 /************************************************************************** @@ -4994,6 +5266,13 @@ FT_BEGIN_HEADER /************************************************************************** * + * @section: + * other_api_data + * + */ + + /************************************************************************** + * * @function: * FT_Face_CheckTrueTypePatents * diff --git a/thirdparty/freetype/include/freetype/ftcache.h b/thirdparty/freetype/include/freetype/ftcache.h index c76869545a..a2072e26b8 100644 --- a/thirdparty/freetype/include/freetype/ftcache.h +++ b/thirdparty/freetype/include/freetype/ftcache.h @@ -43,61 +43,61 @@ FT_BEGIN_HEADER * objects, as well as caching information like character maps and glyph * images while limiting their maximum memory usage. * - * Note that all types and functions begin with the `FTC_` prefix. - * - * The cache is highly portable and thus doesn't know anything about the - * fonts installed on your system, or how to access them. This implies - * the following scheme: - * - * First, available or installed font faces are uniquely identified by - * @FTC_FaceID values, provided to the cache by the client. Note that - * the cache only stores and compares these values, and doesn't try to - * interpret them in any way. - * - * Second, the cache calls, only when needed, a client-provided function - * to convert an @FTC_FaceID into a new @FT_Face object. The latter is - * then completely managed by the cache, including its termination - * through @FT_Done_Face. To monitor termination of face objects, the - * finalizer callback in the `generic` field of the @FT_Face object can - * be used, which might also be used to store the @FTC_FaceID of the - * face. - * - * Clients are free to map face IDs to anything else. The most simple - * usage is to associate them to a (pathname,face_index) pair that is - * used to call @FT_New_Face. However, more complex schemes are also - * possible. + * Note that all types and functions begin with the `FTC_` prefix rather + * than the usual `FT_` prefix in the rest of FreeType. + * + * The cache is highly portable and, thus, doesn't know anything about + * the fonts installed on your system, or how to access them. Therefore, + * it requires the following. + * + * * @FTC_FaceID, an arbitrary non-zero value that uniquely identifies + * available or installed font faces, has to be provided to the + * cache by the client. Note that the cache only stores and compares + * these values and doesn't try to interpret them in any way, but they + * have to be persistent on the client side. + * + * * @FTC_Face_Requester, a method to convert an @FTC_FaceID into a new + * @FT_Face object when necessary, has to be provided to the cache by + * the client. The @FT_Face object is completely managed by the cache, + * including its termination through @FT_Done_Face. To monitor + * termination of face objects, the finalizer callback in the `generic` + * field of the @FT_Face object can be used, which might also be used + * to store the @FTC_FaceID of the face. + * + * Clients are free to map face IDs to anything useful. The most simple + * usage is, for example, to associate them to a `{pathname,face_index}` + * pair that is then used by @FTC_Face_Requester to call @FT_New_Face. + * However, more complex schemes are also possible. * * Note that for the cache to work correctly, the face ID values must be * **persistent**, which means that the contents they point to should not * change at runtime, or that their value should not become invalid. - * * If this is unavoidable (e.g., when a font is uninstalled at runtime), - * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let + * you should call @FTC_Manager_RemoveFaceID as soon as possible to let * the cache get rid of any references to the old @FTC_FaceID it may keep * internally. Failure to do so will lead to incorrect behaviour or even - * crashes. + * crashes in @FTC_Face_Requester. * * To use the cache, start with calling @FTC_Manager_New to create a new * @FTC_Manager object, which models a single cache instance. You can * then look up @FT_Face and @FT_Size objects with - * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively. - * - * If you want to use the charmap caching, call @FTC_CMapCache_New, then - * later use @FTC_CMapCache_Lookup to perform the equivalent of - * @FT_Get_Char_Index, only much faster. - * - * If you want to use the @FT_Glyph caching, call @FTC_ImageCache_New, - * then later use @FTC_ImageCache_Lookup to retrieve the corresponding - * @FT_Glyph objects from the cache. - * - * If you need lots of small bitmaps, it is much more memory efficient to - * call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This - * returns @FTC_SBitRec structures, which are used to store small bitmaps - * directly. (A small bitmap is one whose metrics and dimensions all fit - * into 8-bit integers). - * - * We hope to also provide a kerning cache in the near future. - * + * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively, and + * use them in any FreeType work stream. You can also cache other + * FreeType objects as follows. + * + * * If you want to use the charmap caching, call @FTC_CMapCache_New, + * then later use @FTC_CMapCache_Lookup to perform the equivalent of + * @FT_Get_Char_Index, only much faster. + * + * * If you want to use the @FT_Glyph caching, call @FTC_ImageCache_New, + * then later use @FTC_ImageCache_Lookup to retrieve the corresponding + * @FT_Glyph objects from the cache. + * + * * If you need lots of small bitmaps, it is much more memory-efficient + * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This + * returns @FTC_SBitRec structures, which are used to store small + * bitmaps directly. (A small bitmap is one whose metrics and + * dimensions all fit into 8-bit integers). * * @order: * FTC_Manager diff --git a/thirdparty/freetype/include/freetype/ftchapters.h b/thirdparty/freetype/include/freetype/ftchapters.h index 6a9733ad7c..7566fbd10f 100644 --- a/thirdparty/freetype/include/freetype/ftchapters.h +++ b/thirdparty/freetype/include/freetype/ftchapters.h @@ -31,9 +31,28 @@ * Core API * * @sections: - * version * basic_types - * base_interface + * library_setup + * face_creation + * font_testing_macros + * sizing_and_scaling + * glyph_retrieval + * character_mapping + * information_retrieval + * other_api_data + * + */ + + + /************************************************************************** + * + * @chapter: + * extended_api + * + * @title: + * Extended API + * + * @sections: * glyph_variants * color_management * layer_management diff --git a/thirdparty/freetype/include/freetype/ftdriver.h b/thirdparty/freetype/include/freetype/ftdriver.h index f90946fd17..7af7465bc7 100644 --- a/thirdparty/freetype/include/freetype/ftdriver.h +++ b/thirdparty/freetype/include/freetype/ftdriver.h @@ -134,7 +134,7 @@ FT_BEGIN_HEADER * each being rounded to the nearest pixel edge, taking care of overshoot * suppression at small sizes, stem darkening, and scaling. * - * Hstems (this is, hint values defined in the font to help align + * Hstems (that is, hint values defined in the font to help align * horizontal features) that fall within a blue zone are said to be * 'captured' and are aligned to that zone. Uncaptured stems are moved * in one of four ways, top edge up or down, bottom edge up or down. @@ -446,7 +446,7 @@ FT_BEGIN_HEADER * at smaller sizes. * * For the auto-hinter, stem-darkening is experimental currently and thus - * switched off by default (this is, `no-stem-darkening` is set to TRUE + * switched off by default (that is, `no-stem-darkening` is set to TRUE * by default). Total consistency with the CFF driver is not achieved * right now because the emboldening method differs and glyphs must be * scaled down on the Y-axis to keep outline points inside their @@ -651,11 +651,8 @@ FT_BEGIN_HEADER * Windows~98; only grayscale and B/W rasterizing is supported. * * TT_INTERPRETER_VERSION_38 :: - * Version~38 corresponds to MS rasterizer v.1.9; it is roughly - * equivalent to the hinting provided by DirectWrite ClearType (as can - * be found, for example, in the Internet Explorer~9 running on - * Windows~7). It is used in FreeType to select the 'Infinality' - * subpixel hinting code. The code may be removed in a future version. + * Version~38 is the same Version~40. The original 'Infinality' code is + * no longer available. * * TT_INTERPRETER_VERSION_40 :: * Version~40 corresponds to MS rasterizer v.2.1; it is roughly diff --git a/thirdparty/freetype/include/freetype/ftimage.h b/thirdparty/freetype/include/freetype/ftimage.h index 2e8e6734cc..6baa812560 100644 --- a/thirdparty/freetype/include/freetype/ftimage.h +++ b/thirdparty/freetype/include/freetype/ftimage.h @@ -19,7 +19,7 @@ /************************************************************************** * * Note: A 'raster' is simply a scan-line converter, used to render - * FT_Outlines into FT_Bitmaps. + * `FT_Outline`s into `FT_Bitmap`s. * */ @@ -256,6 +256,12 @@ FT_BEGIN_HEADER * palette :: * A typeless pointer to the bitmap palette; this field is intended for * paletted pixel modes. Not used currently. + * + * @note: + * `width` and `rows` refer to the *physical* size of the bitmap, not the + * *logical* one. For example, if @FT_Pixel_Mode is set to + * `FT_PIXEL_MODE_LCD`, the logical width is a just a third of the + * physical one. */ typedef struct FT_Bitmap_ { @@ -856,7 +862,7 @@ FT_BEGIN_HEADER * @FT_SpanFunc that takes the y~coordinate of the span as a parameter. * * The anti-aliased rasterizer produces coverage values from 0 to 255, - * this is, from completely transparent to completely opaque. + * that is, from completely transparent to completely opaque. */ typedef struct FT_Span_ { diff --git a/thirdparty/freetype/include/freetype/ftlogging.h b/thirdparty/freetype/include/freetype/ftlogging.h index 2246dc8365..53b8b89642 100644 --- a/thirdparty/freetype/include/freetype/ftlogging.h +++ b/thirdparty/freetype/include/freetype/ftlogging.h @@ -62,7 +62,7 @@ FT_BEGIN_HEADER * component. * * ``` - * FT_Trace_Set_Level( "any:7 memory:0 ); + * FT_Trace_Set_Level( "any:7 memory:0" ); * ``` * * @note: diff --git a/thirdparty/freetype/include/freetype/ftmm.h b/thirdparty/freetype/include/freetype/ftmm.h index e381ef3d30..d145128a9b 100644 --- a/thirdparty/freetype/include/freetype/ftmm.h +++ b/thirdparty/freetype/include/freetype/ftmm.h @@ -153,7 +153,7 @@ FT_BEGIN_HEADER * @note: * The fields `minimum`, `def`, and `maximum` are 16.16 fractional values * for TrueType GX and OpenType variation fonts. For Adobe MM fonts, the - * values are integers. + * values are whole numbers (i.e., the fractional part is zero). */ typedef struct FT_Var_Axis_ { @@ -399,8 +399,8 @@ FT_BEGIN_HEADER * * @note: * The design coordinates are 16.16 fractional values for TrueType GX and - * OpenType variation fonts. For Adobe MM fonts, the values are - * integers. + * OpenType variation fonts. For Adobe MM fonts, the values are supposed + * to be whole numbers (i.e., the fractional part is zero). * * [Since 2.8.1] To reset all axes to the default values, call the * function with `num_coords` set to zero and `coords` set to `NULL`. @@ -446,8 +446,8 @@ FT_BEGIN_HEADER * * @note: * The design coordinates are 16.16 fractional values for TrueType GX and - * OpenType variation fonts. For Adobe MM fonts, the values are - * integers. + * OpenType variation fonts. For Adobe MM fonts, the values are whole + * numbers (i.e., the fractional part is zero). * * @since: * 2.7.1 @@ -602,10 +602,12 @@ FT_BEGIN_HEADER * * @note: * Adobe Multiple Master fonts limit the number of designs, and thus the - * length of the weight vector to~16. + * length of the weight vector to 16~elements. * - * If `len` is zero and `weightvector` is `NULL`, the weight vector array - * is reset to the default values. + * If `len` is larger than zero, this function sets the + * @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field (i.e., + * @FT_IS_VARIATION will return true). If `len` is zero, this bit flag + * is unset and the weight vector array is reset to the default values. * * The Adobe documentation also states that the values in the * WeightVector array must total 1.0 +/-~0.001. In practice this does @@ -753,6 +755,45 @@ FT_BEGIN_HEADER FT_Set_Named_Instance( FT_Face face, FT_UInt instance_index ); + + /************************************************************************** + * + * @function: + * FT_Get_Default_Named_Instance + * + * @description: + * Retrieve the index of the default named instance, to be used with + * @FT_Set_Named_Instance. + * + * The default instance of a variation font is that instance for which + * the nth axis coordinate is equal to `axis[n].def` (as specified in the + * @FT_MM_Var structure), with~n covering all axes. + * + * FreeType synthesizes a named instance for the default instance if the + * font does not contain such an entry. + * + * @input: + * face :: + * A handle to the source face. + * + * @output: + * instance_index :: + * The index of the default named instance. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * For Adobe MM fonts (which don't have named instances) this function + * always returns zero for `instance_index`. + * + * @since: + * 2.13.1 + */ + FT_EXPORT( FT_Error ) + FT_Get_Default_Named_Instance( FT_Face face, + FT_UInt *instance_index ); + /* */ diff --git a/thirdparty/freetype/include/freetype/ftoutln.h b/thirdparty/freetype/include/freetype/ftoutln.h index 54434b25f6..f9329ca40c 100644 --- a/thirdparty/freetype/include/freetype/ftoutln.h +++ b/thirdparty/freetype/include/freetype/ftoutln.h @@ -118,7 +118,7 @@ FT_BEGIN_HEADER * attachement. * * Similarly, the function returns success for an empty outline also - * (doing nothing, this is, not calling any emitter); if necessary, you + * (doing nothing, that is, not calling any emitter); if necessary, you * should filter this out, too. */ FT_EXPORT( FT_Error ) diff --git a/thirdparty/freetype/include/freetype/ftrender.h b/thirdparty/freetype/include/freetype/ftrender.h index a8576dab00..0b6fad32e8 100644 --- a/thirdparty/freetype/include/freetype/ftrender.h +++ b/thirdparty/freetype/include/freetype/ftrender.h @@ -158,7 +158,7 @@ FT_BEGIN_HEADER FT_Renderer_GetCBoxFunc get_glyph_cbox; FT_Renderer_SetModeFunc set_mode; - FT_Raster_Funcs* raster_class; + const FT_Raster_Funcs* raster_class; } FT_Renderer_Class; diff --git a/thirdparty/freetype/include/freetype/ftsynth.h b/thirdparty/freetype/include/freetype/ftsynth.h index 5d19697657..af90967dda 100644 --- a/thirdparty/freetype/include/freetype/ftsynth.h +++ b/thirdparty/freetype/include/freetype/ftsynth.h @@ -68,6 +68,18 @@ FT_BEGIN_HEADER FT_EXPORT( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); + /* Precisely adjust the glyph weight either horizontally or vertically. */ + /* The `xdelta` and `ydelta` values are fractions of the face Em size */ + /* (in fixed-point format). Considering that a regular face would have */ + /* stem widths on the order of 0.1 Em, a delta of 0.05 (0x0CCC) should */ + /* be very noticeable. To increase or decrease the weight, use positive */ + /* or negative values, respectively. */ + FT_EXPORT( void ) + FT_GlyphSlot_AdjustWeight( FT_GlyphSlot slot, + FT_Fixed xdelta, + FT_Fixed ydelta ); + + /* Slant an outline glyph to the right by about 12 degrees. */ FT_EXPORT( void ) FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); diff --git a/thirdparty/freetype/include/freetype/ftsystem.h b/thirdparty/freetype/include/freetype/ftsystem.h index a995b078de..3a08f4912c 100644 --- a/thirdparty/freetype/include/freetype/ftsystem.h +++ b/thirdparty/freetype/include/freetype/ftsystem.h @@ -229,8 +229,7 @@ FT_BEGIN_HEADER * A handle to the source stream. * * offset :: - * The offset from the start of the stream to seek to if this is a seek - * operation (see note). + * The offset from the start of the stream to seek to. * * buffer :: * The address of the read buffer. @@ -239,16 +238,9 @@ FT_BEGIN_HEADER * The number of bytes to read from the stream. * * @return: - * The number of bytes effectively read by the stream. - * - * @note: - * This function performs a seek *or* a read operation depending on the - * argument values. If `count` is zero, the operation is a seek to - * `offset` bytes. If `count` is >~0, the operation is a read of `count` - * bytes from the current position in the stream, and the `offset` value - * should be ignored. - * - * For seek operations, a non-zero return value indicates an error. + * If count >~0, return the number of bytes effectively read by the + * stream (after seeking to `offset`). If count ==~0, return the status + * of the seek operation (non-zero indicates an error). * */ typedef unsigned long diff --git a/thirdparty/freetype/include/freetype/internal/compiler-macros.h b/thirdparty/freetype/include/freetype/internal/compiler-macros.h index 7883317fed..6f67650979 100644 --- a/thirdparty/freetype/include/freetype/internal/compiler-macros.h +++ b/thirdparty/freetype/include/freetype/internal/compiler-macros.h @@ -41,8 +41,11 @@ FT_BEGIN_HEADER # if ( defined( __STDC_VERSION__ ) && __STDC_VERSION__ > 201710L ) || \ ( defined( __cplusplus ) && __cplusplus > 201402L ) # define FALL_THROUGH [[__fallthrough__]] -# elif ( defined( __GNUC__ ) && __GNUC__ >= 7 ) || \ - ( defined( __clang__ ) && __clang_major__ >= 10 ) +# elif ( defined( __GNUC__ ) && __GNUC__ >= 7 ) || \ + ( defined( __clang__ ) && \ + ( defined( __apple_build_version__ ) \ + ? __apple_build_version__ >= 12000000 \ + : __clang_major__ >= 10 ) ) # define FALL_THROUGH __attribute__(( __fallthrough__ )) # else # define FALL_THROUGH ( (void)0 ) diff --git a/thirdparty/freetype/include/freetype/internal/ftdrv.h b/thirdparty/freetype/include/freetype/internal/ftdrv.h index f78912ca0c..9001c07ad0 100644 --- a/thirdparty/freetype/include/freetype/internal/ftdrv.h +++ b/thirdparty/freetype/include/freetype/internal/ftdrv.h @@ -157,6 +157,7 @@ FT_BEGIN_HEADER * A handle to a function used to select a new fixed size. It is used * only if @FT_FACE_FLAG_FIXED_SIZES is set. Can be set to 0 if the * scaling done in the base layer suffices. + * * @note: * Most function pointers, with the exception of `load_glyph`, can be set * to 0 to indicate a default behaviour. diff --git a/thirdparty/freetype/include/freetype/internal/ftmmtypes.h b/thirdparty/freetype/include/freetype/internal/ftmmtypes.h index b7c66c35de..c4b21d6144 100644 --- a/thirdparty/freetype/include/freetype/internal/ftmmtypes.h +++ b/thirdparty/freetype/include/freetype/internal/ftmmtypes.h @@ -28,13 +28,19 @@ FT_BEGIN_HEADER typedef struct GX_ItemVarDataRec_ { - FT_UInt itemCount; /* number of delta sets per item */ - FT_UInt regionIdxCount; /* number of region indices */ - FT_UInt* regionIndices; /* array of `regionCount' indices; */ - /* these index `varRegionList' */ - FT_ItemVarDelta* deltaSet; /* array of `itemCount' deltas */ - /* use `innerIndex' for this array */ - + FT_UInt itemCount; /* Number of delta sets per item. */ + FT_UInt regionIdxCount; /* Number of region indices. */ + FT_UInt* regionIndices; /* Array of `regionCount` indices; */ + /* these index `varRegionList`. */ + FT_Byte* deltaSet; /* Array of `itemCount` deltas; */ + /* use `innerIndex` for this array. */ + FT_UShort wordDeltaCount; /* Number of the first 32-bit ints */ + /* or 16-bit ints of `deltaSet` */ + /* depending on `longWords`. */ + FT_Bool longWords; /* If true, `deltaSet` is a 32-bit */ + /* array followed by a 16-bit */ + /* array, otherwise a 16-bit array */ + /* followed by an 8-bit array. */ } GX_ItemVarDataRec, *GX_ItemVarData; diff --git a/thirdparty/freetype/include/freetype/internal/services/svmetric.h b/thirdparty/freetype/include/freetype/internal/services/svmetric.h index e588ea4872..167617ebb3 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svmetric.h +++ b/thirdparty/freetype/include/freetype/internal/services/svmetric.h @@ -77,6 +77,9 @@ FT_BEGIN_HEADER typedef void (*FT_Metrics_Adjust_Func)( FT_Face face ); + typedef FT_Error + (*FT_Size_Reset_Func)( FT_Size size ); + FT_DEFINE_SERVICE( MetricsVariations ) { @@ -90,6 +93,7 @@ FT_BEGIN_HEADER FT_VOrg_Adjust_Func vorg_adjust; FT_Metrics_Adjust_Func metrics_adjust; + FT_Size_Reset_Func size_reset; }; @@ -101,7 +105,8 @@ FT_BEGIN_HEADER tsb_adjust_, \ bsb_adjust_, \ vorg_adjust_, \ - metrics_adjust_ ) \ + metrics_adjust_, \ + size_reset_ ) \ static const FT_Service_MetricsVariationsRec class_ = \ { \ hadvance_adjust_, \ @@ -111,7 +116,8 @@ FT_BEGIN_HEADER tsb_adjust_, \ bsb_adjust_, \ vorg_adjust_, \ - metrics_adjust_ \ + metrics_adjust_, \ + size_reset_ \ }; /* */ diff --git a/thirdparty/freetype/include/freetype/internal/services/svmm.h b/thirdparty/freetype/include/freetype/internal/services/svmm.h index d94204232e..7e76ab8324 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svmm.h +++ b/thirdparty/freetype/include/freetype/internal/services/svmm.h @@ -60,9 +60,9 @@ FT_BEGIN_HEADER /* use return value -1 to indicate that the new coordinates */ /* are equal to the current ones; no changes are thus needed */ typedef FT_Error - (*FT_Set_MM_Blend_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); + (*FT_Set_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); typedef FT_Error (*FT_Get_Var_Design_Func)( FT_Face face, @@ -70,13 +70,17 @@ FT_BEGIN_HEADER FT_Fixed* coords ); typedef FT_Error - (*FT_Set_Instance_Func)( FT_Face face, - FT_UInt instance_index ); + (*FT_Set_Named_Instance_Func)( FT_Face face, + FT_UInt instance_index ); typedef FT_Error - (*FT_Get_MM_Blend_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); + (*FT_Get_Default_Named_Instance_Func)( FT_Face face, + FT_UInt *instance_index ); + + typedef FT_Error + (*FT_Get_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); typedef FT_Error (*FT_Get_Var_Blend_Func)( FT_Face face, @@ -86,7 +90,7 @@ FT_BEGIN_HEADER FT_MM_Var* *mm_var ); typedef void - (*FT_Done_Blend_Func)( FT_Face ); + (*FT_Done_Blend_Func)( FT_Face face ); typedef FT_Error (*FT_Set_MM_WeightVector_Func)( FT_Face face, @@ -98,6 +102,9 @@ FT_BEGIN_HEADER FT_UInt* len, FT_Fixed* weight_vector ); + typedef void + (*FT_Construct_PS_Name_Func)( FT_Face face ); + typedef FT_Error (*FT_Var_Load_Delta_Set_Idx_Map_Func)( FT_Face face, FT_ULong offset, @@ -134,11 +141,13 @@ FT_BEGIN_HEADER FT_Get_MM_Var_Func get_mm_var; FT_Set_Var_Design_Func set_var_design; FT_Get_Var_Design_Func get_var_design; - FT_Set_Instance_Func set_instance; + FT_Set_Named_Instance_Func set_named_instance; + FT_Get_Default_Named_Instance_Func get_default_named_instance; FT_Set_MM_WeightVector_Func set_mm_weightvector; FT_Get_MM_WeightVector_Func get_mm_weightvector; /* for internal use; only needed for code sharing between modules */ + FT_Construct_PS_Name_Func construct_ps_name; FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map; FT_Var_Load_Item_Var_Store_Func load_item_var_store; FT_Var_Get_Item_Delta_Func get_item_delta; @@ -149,43 +158,49 @@ FT_BEGIN_HEADER }; -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - set_weightvector_, \ - get_weightvector_, \ - load_delta_set_idx_map_, \ - load_item_var_store_, \ - get_item_delta_, \ - done_item_var_store_, \ - done_delta_set_idx_map_, \ - get_var_blend_, \ - done_blend_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_blend_, \ - get_mm_var_, \ - set_var_design_, \ - get_var_design_, \ - set_instance_, \ - set_weightvector_, \ - get_weightvector_, \ - load_delta_set_idx_map_, \ - load_item_var_store_, \ - get_item_delta_, \ - done_item_var_store_, \ - done_delta_set_idx_map_, \ - get_var_blend_, \ - done_blend_ \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_named_instance_, \ + get_default_named_instance_, \ + set_mm_weightvector_, \ + get_mm_weightvector_, \ + \ + construct_ps_name_, \ + load_delta_set_idx_map_, \ + load_item_var_store_, \ + get_item_delta_, \ + done_item_var_store_, \ + done_delta_set_idx_map_, \ + get_var_blend_, \ + done_blend_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_named_instance_, \ + get_default_named_instance_, \ + set_mm_weightvector_, \ + get_mm_weightvector_, \ + \ + construct_ps_name_, \ + load_delta_set_idx_map_, \ + load_item_var_store_, \ + get_item_delta_, \ + done_item_var_store_, \ + done_delta_set_idx_map_, \ + get_var_blend_, \ + done_blend_ \ }; /* */ diff --git a/thirdparty/freetype/include/freetype/internal/services/svpscmap.h b/thirdparty/freetype/include/freetype/internal/services/svpscmap.h index fd99d857e4..6e599f3aab 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svpscmap.h +++ b/thirdparty/freetype/include/freetype/internal/services/svpscmap.h @@ -97,7 +97,7 @@ FT_BEGIN_HEADER (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, FT_UInt32 unicode ); - typedef FT_UInt32 + typedef FT_UInt (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, FT_UInt32 *unicode ); diff --git a/thirdparty/freetype/include/freetype/internal/t1types.h b/thirdparty/freetype/include/freetype/internal/t1types.h index 5a105c5879..b9c94398fd 100644 --- a/thirdparty/freetype/include/freetype/internal/t1types.h +++ b/thirdparty/freetype/include/freetype/internal/t1types.h @@ -201,30 +201,30 @@ FT_BEGIN_HEADER typedef struct T1_FaceRec_ { - FT_FaceRec root; - T1_FontRec type1; - const void* psnames; - const void* psaux; - const void* afm_data; - FT_CharMapRec charmaprecs[2]; - FT_CharMap charmaps[2]; + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; + const void* afm_data; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; /* support for Multiple Masters fonts */ - PS_Blend blend; + PS_Blend blend; /* undocumented, optional: indices of subroutines that express */ /* the NormalizeDesignVector and the ConvertDesignVector procedure, */ /* respectively, as Type 2 charstrings; -1 if keywords not present */ - FT_Int ndv_idx; - FT_Int cdv_idx; + FT_Int ndv_idx; + FT_Int cdv_idx; /* undocumented, optional: has the same meaning as len_buildchar */ /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */ - FT_UInt len_buildchar; - FT_Long* buildchar; + FT_UInt len_buildchar; + FT_Long* buildchar; /* since version 2.1 - interface to PostScript hinter */ - const void* pshinter; + const void* pshinter; } T1_FaceRec; diff --git a/thirdparty/freetype/include/freetype/internal/tttypes.h b/thirdparty/freetype/include/freetype/internal/tttypes.h index 3b521924ca..984121a0e4 100644 --- a/thirdparty/freetype/include/freetype/internal/tttypes.h +++ b/thirdparty/freetype/include/freetype/internal/tttypes.h @@ -779,13 +779,15 @@ FT_BEGIN_HEADER /************************************************************************** * * @struct: - * TT_Post_20Rec + * TT_Post_NamesRec * * @description: - * Postscript names sub-table, format 2.0. Stores the PS name of each - * glyph in the font face. + * Postscript names table, either format 2.0 or 2.5. * * @fields: + * loaded :: + * A flag to indicate whether the PS names are loaded. + * * num_glyphs :: * The number of named glyphs in the table. * @@ -798,68 +800,13 @@ FT_BEGIN_HEADER * glyph_names :: * The PS names not in Mac Encoding. */ - typedef struct TT_Post_20Rec_ + typedef struct TT_Post_NamesRec_ { + FT_Bool loaded; FT_UShort num_glyphs; FT_UShort num_names; FT_UShort* glyph_indices; - FT_Char** glyph_names; - - } TT_Post_20Rec, *TT_Post_20; - - - /************************************************************************** - * - * @struct: - * TT_Post_25Rec - * - * @description: - * Postscript names sub-table, format 2.5. Stores the PS name of each - * glyph in the font face. - * - * @fields: - * num_glyphs :: - * The number of glyphs in the table. - * - * offsets :: - * An array of signed offsets in a normal Mac Postscript name encoding. - */ - typedef struct TT_Post_25_ - { - FT_UShort num_glyphs; - FT_Char* offsets; - - } TT_Post_25Rec, *TT_Post_25; - - - /************************************************************************** - * - * @struct: - * TT_Post_NamesRec - * - * @description: - * Postscript names table, either format 2.0 or 2.5. - * - * @fields: - * loaded :: - * A flag to indicate whether the PS names are loaded. - * - * format_20 :: - * The sub-table used for format 2.0. - * - * format_25 :: - * The sub-table used for format 2.5. - */ - typedef struct TT_Post_NamesRec_ - { - FT_Bool loaded; - - union - { - TT_Post_20Rec format_20; - TT_Post_25Rec format_25; - - } names; + FT_Byte** glyph_names; } TT_Post_NamesRec, *TT_Post_Names; @@ -1253,12 +1200,16 @@ FT_BEGIN_HEADER * mm :: * A pointer to the Multiple Masters service. * - * var :: - * A pointer to the Metrics Variations service. + * tt_var :: + * A pointer to the Metrics Variations service for the "truetype" + * driver. * - * hdmx :: - * The face's horizontal device metrics ('hdmx' table). This table is - * optional in TrueType/OpenType fonts. + * face_var :: + * A pointer to the Metrics Variations service for this `TT_Face`'s + * driver. + * + * psaux :: + * A pointer to the PostScript Auxiliary service. * * gasp :: * The grid-fitting and scaling properties table ('gasp'). This table @@ -1364,6 +1315,12 @@ FT_BEGIN_HEADER * var_postscript_prefix_len :: * The length of the `var_postscript_prefix` string. * + * var_default_named_instance :: + * The index of the default named instance. + * + * non_var_style_name :: + * The non-variation style name, used as a backup. + * * horz_metrics_size :: * The size of the 'hmtx' table. * @@ -1410,14 +1367,6 @@ FT_BEGIN_HEADER * A mapping between the strike indices exposed by the API and the * indices used in the font's sbit table. * - * cpal :: - * A pointer to data related to the 'CPAL' table. `NULL` if the table - * is not available. - * - * colr :: - * A pointer to data related to the 'COLR' table. `NULL` if the table - * is not available. - * * kern_table :: * A pointer to the 'kern' table. * @@ -1458,6 +1407,18 @@ FT_BEGIN_HEADER * * ebdt_size :: * The size of the sbit data table. + * + * cpal :: + * A pointer to data related to the 'CPAL' table. `NULL` if the table + * is not available. + * + * colr :: + * A pointer to data related to the 'COLR' table. `NULL` if the table + * is not available. + * + * svg :: + * A pointer to data related to the 'SVG' table. `NULL` if the table + * is not available. */ typedef struct TT_FaceRec_ { @@ -1508,8 +1469,14 @@ FT_BEGIN_HEADER void* mm; /* a typeless pointer to the FT_Service_MetricsVariationsRec table */ - /* used to handle the HVAR, VVAR, and MVAR OpenType tables */ - void* var; + /* used to handle the HVAR, VVAR, and MVAR OpenType tables by the */ + /* "truetype" driver */ + void* tt_var; + + /* a typeless pointer to the FT_Service_MetricsVariationsRec table */ + /* used to handle the HVAR, VVAR, and MVAR OpenType tables by this */ + /* TT_Face's driver */ + void* face_var; /* since 2.13.1 */ #endif /* a typeless pointer to the PostScript Aux service */ @@ -1591,6 +1558,9 @@ FT_BEGIN_HEADER const char* var_postscript_prefix; /* since 2.7.2 */ FT_UInt var_postscript_prefix_len; /* since 2.7.2 */ + FT_UInt var_default_named_instance; /* since 2.13.1 */ + + const char* non_var_style_name; /* since 2.13.1 */ #endif /* since version 2.2 */ diff --git a/thirdparty/freetype/src/autofit/afcjk.c b/thirdparty/freetype/src/autofit/afcjk.c index 5daefff359..af775b190c 100644 --- a/thirdparty/freetype/src/autofit/afcjk.c +++ b/thirdparty/freetype/src/autofit/afcjk.c @@ -417,16 +417,14 @@ { FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; + FT_Int pp, first, last; - for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) + last = -1; + for ( nn = 0; nn < outline.n_contours; nn++ ) { - FT_Int pp; - - - last = outline.contours[nn]; + first = last + 1; + last = outline.contours[nn]; /* Avoid single-point contours since they are never rasterized. */ /* In some fonts, they correspond to mark attachment points */ @@ -569,8 +567,8 @@ af_cjk_metrics_check_digits( AF_CJKMetrics metrics, FT_Face face ) { - FT_Bool started = 0, same_width = 1; - FT_Fixed advance = 0, old_advance = 0; + FT_Bool started = 0, same_width = 1; + FT_Long advance = 0, old_advance = 0; /* If HarfBuzz is not available, we need a pointer to a single */ /* unsigned long value. */ @@ -635,10 +633,11 @@ /* Initialize global metrics. */ FT_LOCAL_DEF( FT_Error ) - af_cjk_metrics_init( AF_CJKMetrics metrics, - FT_Face face ) + af_cjk_metrics_init( AF_StyleMetrics metrics_, /* AF_CJKMetrics */ + FT_Face face ) { - FT_CharMap oldmap = face->charmap; + AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_; + FT_CharMap oldmap = face->charmap; metrics->units_per_em = face->units_per_EM; @@ -756,9 +755,12 @@ /* Scale global values in both directions. */ FT_LOCAL_DEF( void ) - af_cjk_metrics_scale( AF_CJKMetrics metrics, - AF_Scaler scaler ) + af_cjk_metrics_scale( AF_StyleMetrics metrics_, /* AF_CJKMetrics */ + AF_Scaler scaler ) { + AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_; + + /* we copy the whole structure since the x and y scaling values */ /* are not modified, contrary to e.g. the `latin' auto-hinter */ metrics->root.scaler = *scaler; @@ -771,11 +773,14 @@ /* Extract standard_width from writing system/script specific */ /* metrics class. */ - FT_LOCAL_DEF( void ) - af_cjk_get_standard_widths( AF_CJKMetrics metrics, - FT_Pos* stdHW, - FT_Pos* stdVW ) + FT_CALLBACK_DEF( void ) + af_cjk_get_standard_widths( AF_StyleMetrics metrics_, /* AF_CJKMetrics */ + FT_Pos* stdHW, + FT_Pos* stdVW ) { + AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_; + + if ( stdHW ) *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; @@ -1376,9 +1381,10 @@ /* Initalize hinting engine. */ FT_LOCAL_DEF( FT_Error ) - af_cjk_hints_init( AF_GlyphHints hints, - AF_CJKMetrics metrics ) + af_cjk_hints_init( AF_GlyphHints hints, + AF_StyleMetrics metrics_ ) /* AF_CJKMetrics */ { + AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_; FT_Render_Mode mode; FT_UInt32 scaler_flags, other_flags; @@ -2268,11 +2274,13 @@ /* Apply the complete hinting algorithm to a CJK glyph. */ FT_LOCAL_DEF( FT_Error ) - af_cjk_hints_apply( FT_UInt glyph_index, - AF_GlyphHints hints, - FT_Outline* outline, - AF_CJKMetrics metrics ) + af_cjk_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, + FT_Outline* outline, + AF_StyleMetrics metrics_ ) /* AF_CJKMetrics */ { + AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_; + FT_Error error; int dim; diff --git a/thirdparty/freetype/src/autofit/afcjk.h b/thirdparty/freetype/src/autofit/afcjk.h index bd7b81b3e2..f380ef6e03 100644 --- a/thirdparty/freetype/src/autofit/afcjk.h +++ b/thirdparty/freetype/src/autofit/afcjk.h @@ -103,22 +103,22 @@ FT_BEGIN_HEADER #ifdef AF_CONFIG_OPTION_CJK FT_LOCAL( FT_Error ) - af_cjk_metrics_init( AF_CJKMetrics metrics, - FT_Face face ); + af_cjk_metrics_init( AF_StyleMetrics metrics, + FT_Face face ); FT_LOCAL( void ) - af_cjk_metrics_scale( AF_CJKMetrics metrics, - AF_Scaler scaler ); + af_cjk_metrics_scale( AF_StyleMetrics metrics, + AF_Scaler scaler ); FT_LOCAL( FT_Error ) - af_cjk_hints_init( AF_GlyphHints hints, - AF_CJKMetrics metrics ); + af_cjk_hints_init( AF_GlyphHints hints, + AF_StyleMetrics metrics ); FT_LOCAL( FT_Error ) - af_cjk_hints_apply( FT_UInt glyph_index, - AF_GlyphHints hints, - FT_Outline* outline, - AF_CJKMetrics metrics ); + af_cjk_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, + FT_Outline* outline, + AF_StyleMetrics metrics ); /* shared; called from afindic.c */ FT_LOCAL( void ) diff --git a/thirdparty/freetype/src/autofit/afglobal.c b/thirdparty/freetype/src/autofit/afglobal.c index ede27eb166..b1957570f0 100644 --- a/thirdparty/freetype/src/autofit/afglobal.c +++ b/thirdparty/freetype/src/autofit/afglobal.c @@ -376,8 +376,11 @@ FT_LOCAL_DEF( void ) - af_face_globals_free( AF_FaceGlobals globals ) + af_face_globals_free( void* globals_ ) { + AF_FaceGlobals globals = (AF_FaceGlobals)globals_; + + if ( globals ) { FT_Memory memory = globals->face->memory; diff --git a/thirdparty/freetype/src/autofit/afglobal.h b/thirdparty/freetype/src/autofit/afglobal.h index 83a7c2ff15..66170e419d 100644 --- a/thirdparty/freetype/src/autofit/afglobal.h +++ b/thirdparty/freetype/src/autofit/afglobal.h @@ -156,7 +156,7 @@ FT_BEGIN_HEADER AF_StyleMetrics *ametrics ); FT_LOCAL( void ) - af_face_globals_free( AF_FaceGlobals globals ); + af_face_globals_free( void* globals ); FT_LOCAL( FT_Bool ) af_face_globals_is_digit( AF_FaceGlobals globals, diff --git a/thirdparty/freetype/src/autofit/afhints.c b/thirdparty/freetype/src/autofit/afhints.c index 6515af9f04..e4a378fbf7 100644 --- a/thirdparty/freetype/src/autofit/afhints.c +++ b/thirdparty/freetype/src/autofit/afhints.c @@ -320,8 +320,9 @@ static char* - af_print_idx( char* p, - int idx ) + af_print_idx( char* p, + size_t n, + int idx ) { if ( idx == -1 ) { @@ -330,7 +331,7 @@ p[2] = '\0'; } else - ft_sprintf( p, "%d", idx ); + ft_snprintf( p, n, "%d", idx ); return p; } @@ -457,12 +458,12 @@ " %5d %5d %7.2f %7.2f %7.2f %7.2f" " %5s %5s %5s %5s\n", point_idx, - af_print_idx( buf1, + af_print_idx( buf1, 16, af_get_edge_index( hints, segment_idx_1, 1 ) ), - af_print_idx( buf2, segment_idx_1 ), - af_print_idx( buf3, + af_print_idx( buf2, 16, segment_idx_1 ), + af_print_idx( buf3, 16, af_get_edge_index( hints, segment_idx_0, 0 ) ), - af_print_idx( buf4, segment_idx_0 ), + af_print_idx( buf4, 16, segment_idx_0 ), ( point->flags & AF_FLAG_NEAR ) ? " near " : ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) @@ -476,18 +477,22 @@ (double)point->x / 64, (double)point->y / 64, - af_print_idx( buf5, af_get_strong_edge_index( hints, - point->before, - 1 ) ), - af_print_idx( buf6, af_get_strong_edge_index( hints, - point->after, - 1 ) ), - af_print_idx( buf7, af_get_strong_edge_index( hints, - point->before, - 0 ) ), - af_print_idx( buf8, af_get_strong_edge_index( hints, - point->after, - 0 ) ) )); + af_print_idx( buf5, 16, + af_get_strong_edge_index( hints, + point->before, + 1 ) ), + af_print_idx( buf6, 16, + af_get_strong_edge_index( hints, + point->after, + 1 ) ), + af_print_idx( buf7, 16, + af_get_strong_edge_index( hints, + point->before, + 0 ) ), + af_print_idx( buf8, 16, + af_get_strong_edge_index( hints, + point->after, + 0 ) ) )); } AF_DUMP(( "\n" )); } @@ -574,9 +579,12 @@ AF_INDEX_NUM( seg->first, points ), AF_INDEX_NUM( seg->last, points ), - af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ), - af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ), - af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ), + af_print_idx( buf1, 16, + AF_INDEX_NUM( seg->link, segments ) ), + af_print_idx( buf2, 16, + AF_INDEX_NUM( seg->serif, segments ) ), + af_print_idx( buf3, 16, + AF_INDEX_NUM( seg->edge, edges ) ), seg->height, seg->height - ( seg->max_coord - seg->min_coord ), @@ -716,8 +724,10 @@ AF_INDEX_NUM( edge, edges ), (double)(int)edge->opos / 64, af_dir_str( (AF_Direction)edge->dir ), - af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ), - af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ), + af_print_idx( buf1, 16, + AF_INDEX_NUM( edge->link, edges ) ), + af_print_idx( buf2, 16, + AF_INDEX_NUM( edge->serif, edges ) ), edge->blue_edge ? 'y' : 'n', (double)edge->opos / 64, diff --git a/thirdparty/freetype/src/autofit/afindic.c b/thirdparty/freetype/src/autofit/afindic.c index 289a09d71d..7fb12c63d5 100644 --- a/thirdparty/freetype/src/autofit/afindic.c +++ b/thirdparty/freetype/src/autofit/afindic.c @@ -28,9 +28,12 @@ static FT_Error - af_indic_metrics_init( AF_CJKMetrics metrics, - FT_Face face ) + af_indic_metrics_init( AF_StyleMetrics metrics_, /* AF_CJKMetrics */ + FT_Face face ) { + AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_; + + /* skip blue zone init in CJK routines */ FT_CharMap oldmap = face->charmap; @@ -55,8 +58,8 @@ static void - af_indic_metrics_scale( AF_CJKMetrics metrics, - AF_Scaler scaler ) + af_indic_metrics_scale( AF_StyleMetrics metrics, + AF_Scaler scaler ) { /* use CJK routines */ af_cjk_metrics_scale( metrics, scaler ); @@ -64,8 +67,8 @@ static FT_Error - af_indic_hints_init( AF_GlyphHints hints, - AF_CJKMetrics metrics ) + af_indic_hints_init( AF_GlyphHints hints, + AF_StyleMetrics metrics ) { /* use CJK routines */ return af_cjk_hints_init( hints, metrics ); @@ -73,10 +76,10 @@ static FT_Error - af_indic_hints_apply( FT_UInt glyph_index, - AF_GlyphHints hints, - FT_Outline* outline, - AF_CJKMetrics metrics ) + af_indic_hints_apply( FT_UInt glyph_index, + AF_GlyphHints hints, + FT_Outline* outline, + AF_StyleMetrics metrics ) { /* use CJK routines */ return af_cjk_hints_apply( glyph_index, hints, outline, metrics ); @@ -87,10 +90,13 @@ /* metrics class. */ static void - af_indic_get_standard_widths( AF_CJKMetrics metrics, - FT_Pos* stdHW, - FT_Pos* stdVW ) + af_indic_get_standard_widths( AF_StyleMetrics metrics_, /* AF_CJKMetrics */ + FT_Pos* stdHW, + FT_Pos* stdVW ) { + AF_CJKMetrics metrics = (AF_CJKMetrics)metrics_; + + if ( stdHW ) *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; diff --git a/thirdparty/freetype/src/autofit/aflatin.c b/thirdparty/freetype/src/autofit/aflatin.c index 4b3c59b3c3..46c6e450a8 100644 --- a/thirdparty/freetype/src/autofit/aflatin.c +++ b/thirdparty/freetype/src/autofit/aflatin.c @@ -496,23 +496,20 @@ /* now compute min or max point indices and coordinates */ points = outline.points; best_point = -1; + best_contour_first = -1; + best_contour_last = -1; best_y = 0; /* make compiler happy */ - best_contour_first = 0; /* ditto */ - best_contour_last = 0; /* ditto */ { FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; + FT_Int pp, first, last; - for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) + last = -1; + for ( nn = 0; nn < outline.n_contours; nn++ ) { - FT_Int old_best_point = best_point; - FT_Int pp; - - - last = outline.contours[nn]; + first = last + 1; + last = outline.contours[nn]; /* Avoid single-point contours since they are never */ /* rasterized. In some fonts, they correspond to mark */ @@ -551,7 +548,7 @@ } } - if ( best_point != old_best_point ) + if ( best_point > best_contour_last ) { best_contour_first = first; best_contour_last = last; @@ -1068,8 +1065,8 @@ af_latin_metrics_check_digits( AF_LatinMetrics metrics, FT_Face face ) { - FT_Bool started = 0, same_width = 1; - FT_Fixed advance = 0, old_advance = 0; + FT_Bool started = 0, same_width = 1; + FT_Long advance = 0, old_advance = 0; /* If HarfBuzz is not available, we need a pointer to a single */ /* unsigned long value. */ @@ -1134,9 +1131,11 @@ /* Initialize global metrics. */ FT_LOCAL_DEF( FT_Error ) - af_latin_metrics_init( AF_LatinMetrics metrics, + af_latin_metrics_init( AF_StyleMetrics metrics_, /* AF_LatinMetrics */ FT_Face face ) { + AF_LatinMetrics metrics = (AF_LatinMetrics)metrics_; + FT_Error error = FT_Err_Ok; FT_CharMap oldmap = face->charmap; @@ -1489,9 +1488,12 @@ /* Scale global values in both directions. */ FT_LOCAL_DEF( void ) - af_latin_metrics_scale( AF_LatinMetrics metrics, + af_latin_metrics_scale( AF_StyleMetrics metrics_, /* AF_LatinMetrics */ AF_Scaler scaler ) { + AF_LatinMetrics metrics = (AF_LatinMetrics)metrics_; + + metrics->root.scaler.render_mode = scaler->render_mode; metrics->root.scaler.face = scaler->face; metrics->root.scaler.flags = scaler->flags; @@ -1504,11 +1506,14 @@ /* Extract standard_width from writing system/script specific */ /* metrics class. */ - FT_LOCAL_DEF( void ) - af_latin_get_standard_widths( AF_LatinMetrics metrics, + FT_CALLBACK_DEF( void ) + af_latin_get_standard_widths( AF_StyleMetrics metrics_, /* AF_LatinMetrics */ FT_Pos* stdHW, FT_Pos* stdVW ) { + AF_LatinMetrics metrics = (AF_LatinMetrics)metrics_; + + if ( stdHW ) *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; @@ -2041,7 +2046,7 @@ max = seg2->max_coord; /* compute maximum coordinate difference of the two segments */ - /* (this is, how much they overlap) */ + /* (that is, how much they overlap) */ len = max - min; if ( len >= len_threshold ) { @@ -2610,8 +2615,10 @@ static FT_Error af_latin_hints_init( AF_GlyphHints hints, - AF_LatinMetrics metrics ) + AF_StyleMetrics metrics_ ) /* AF_LatinMetrics */ { + AF_LatinMetrics metrics = (AF_LatinMetrics)metrics_; + FT_Render_Mode mode; FT_UInt32 scaler_flags, other_flags; FT_Face face = metrics->root.scaler.face; @@ -3547,8 +3554,10 @@ af_latin_hints_apply( FT_UInt glyph_index, AF_GlyphHints hints, FT_Outline* outline, - AF_LatinMetrics metrics ) + AF_StyleMetrics metrics_ ) /* AF_LatinMetrics */ { + AF_LatinMetrics metrics = (AF_LatinMetrics)metrics_; + FT_Error error; int dim; diff --git a/thirdparty/freetype/src/autofit/aflatin.h b/thirdparty/freetype/src/autofit/aflatin.h index 3c6a7ee4f6..31aa91d3bd 100644 --- a/thirdparty/freetype/src/autofit/aflatin.h +++ b/thirdparty/freetype/src/autofit/aflatin.h @@ -116,11 +116,11 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - af_latin_metrics_init( AF_LatinMetrics metrics, + af_latin_metrics_init( AF_StyleMetrics metrics, FT_Face face ); FT_LOCAL( void ) - af_latin_metrics_scale( AF_LatinMetrics metrics, + af_latin_metrics_scale( AF_StyleMetrics metrics, AF_Scaler scaler ); FT_LOCAL( void ) diff --git a/thirdparty/freetype/src/autofit/afloader.c b/thirdparty/freetype/src/autofit/afloader.c index c8082796fe..7c47d562af 100644 --- a/thirdparty/freetype/src/autofit/afloader.c +++ b/thirdparty/freetype/src/autofit/afloader.c @@ -55,10 +55,8 @@ error = af_face_globals_new( face, &loader->globals, module ); if ( !error ) { - face->autohint.data = - (FT_Pointer)loader->globals; - face->autohint.finalizer = - (FT_Generic_Finalizer)af_face_globals_free; + face->autohint.data = (FT_Pointer)loader->globals; + face->autohint.finalizer = af_face_globals_free; } } diff --git a/thirdparty/freetype/src/autofit/afmodule.c b/thirdparty/freetype/src/autofit/afmodule.c index 92e5156ab2..20a6b96bc4 100644 --- a/thirdparty/freetype/src/autofit/afmodule.c +++ b/thirdparty/freetype/src/autofit/afmodule.c @@ -89,10 +89,8 @@ error = af_face_globals_new( face, &globals, module ); if ( !error ) { - face->autohint.data = - (FT_Pointer)globals; - face->autohint.finalizer = - (FT_Generic_Finalizer)af_face_globals_free; + face->autohint.data = (FT_Pointer)globals; + face->autohint.finalizer = af_face_globals_free; } } @@ -374,8 +372,9 @@ FT_DEFINE_SERVICE_PROPERTIESREC( af_service_properties, - (FT_Properties_SetFunc)af_property_set, /* set_property */ - (FT_Properties_GetFunc)af_property_get ) /* get_property */ + af_property_set, /* FT_Properties_SetFunc set_property */ + af_property_get /* FT_Properties_GetFunc get_property */ + ) FT_DEFINE_SERVICEDESCREC1( @@ -430,12 +429,14 @@ FT_CALLBACK_DEF( FT_Error ) - af_autofitter_load_glyph( AF_Module module, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ) + af_autofitter_load_glyph( FT_AutoHinter module_, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) { + AF_Module module = (AF_Module)module_; + FT_Error error = FT_Err_Ok; FT_Memory memory = module->root.library->memory; @@ -499,10 +500,10 @@ FT_DEFINE_AUTOHINTER_INTERFACE( af_autofitter_interface, - NULL, /* reset_face */ - NULL, /* get_global_hints */ - NULL, /* done_global_hints */ - (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph /* load_glyph */ + NULL, /* FT_AutoHinter_GlobalResetFunc reset_face */ + NULL, /* FT_AutoHinter_GlobalGetFunc get_global_hints */ + NULL, /* FT_AutoHinter_GlobalDoneFunc done_global_hints */ + af_autofitter_load_glyph /* FT_AutoHinter_GlyphLoadFunc load_glyph */ ) FT_DEFINE_MODULE( @@ -517,9 +518,9 @@ (const void*)&af_autofitter_interface, - (FT_Module_Constructor)af_autofitter_init, /* module_init */ - (FT_Module_Destructor) af_autofitter_done, /* module_done */ - (FT_Module_Requester) af_get_interface /* get_interface */ + af_autofitter_init, /* FT_Module_Constructor module_init */ + af_autofitter_done, /* FT_Module_Destructor module_done */ + af_get_interface /* FT_Module_Requester get_interface */ ) diff --git a/thirdparty/freetype/src/autofit/afshaper.c b/thirdparty/freetype/src/autofit/afshaper.c index 1b8b870e89..abc6f1d292 100644 --- a/thirdparty/freetype/src/autofit/afshaper.c +++ b/thirdparty/freetype/src/autofit/afshaper.c @@ -258,7 +258,7 @@ /* * We now check whether we can construct blue zones, using glyphs * covered by the feature only. In case there is not a single zone - * (this is, not a single character is covered), we skip this coverage. + * (that is, not a single character is covered), we skip this coverage. * */ if ( style_class->coverage != AF_COVERAGE_DEFAULT ) @@ -313,9 +313,9 @@ * hinted and usually rendered glyph. * * Consider the superscript feature of font `pala.ttf': Some of the - * glyphs are `real', this is, they have a zero vertical offset, but + * glyphs are `real', that is, they have a zero vertical offset, but * most of them are small caps glyphs shifted up to the superscript - * position (this is, the `sups' feature is present in both the GSUB and + * position (that is, the `sups' feature is present in both the GSUB and * GPOS tables). The code for blue zones computation actually uses a * feature's y offset so that the `real' glyphs get correct hints. But * later on it is impossible to decide whether a glyph index belongs to, diff --git a/thirdparty/freetype/src/autofit/ft-hb.c b/thirdparty/freetype/src/autofit/ft-hb.c index 09a8401c4a..71aee04550 100644 --- a/thirdparty/freetype/src/autofit/ft-hb.c +++ b/thirdparty/freetype/src/autofit/ft-hb.c @@ -108,7 +108,7 @@ hb_ft_font_create_ (FT_Face ft_face, #else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */ /* ANSI C doesn't like empty source files */ -typedef int _ft_hb_dummy; +typedef int ft_hb_dummy_; #endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */ diff --git a/thirdparty/freetype/src/base/ftbbox.c b/thirdparty/freetype/src/base/ftbbox.c index 7dd71882ea..385fea4040 100644 --- a/thirdparty/freetype/src/base/ftbbox.c +++ b/thirdparty/freetype/src/base/ftbbox.c @@ -82,10 +82,13 @@ * @Return: * Always 0. Needed for the interface only. */ - static int - BBox_Move_To( FT_Vector* to, - TBBox_Rec* user ) + FT_CALLBACK_DEF( int ) + BBox_Move_To( const FT_Vector* to, + void* user_ ) { + TBBox_Rec* user = (TBBox_Rec*)user_; + + FT_UPDATE_BBOX( to, user->bbox ); user->last = *to; @@ -116,10 +119,13 @@ * @Return: * Always 0. Needed for the interface only. */ - static int - BBox_Line_To( FT_Vector* to, - TBBox_Rec* user ) + FT_CALLBACK_DEF( int ) + BBox_Line_To( const FT_Vector* to, + void* user_ ) { + TBBox_Rec* user = (TBBox_Rec*)user_; + + user->last = *to; return 0; @@ -205,11 +211,14 @@ * In the case of a non-monotonous arc, we compute directly the * extremum coordinates, as it is sufficiently fast. */ - static int - BBox_Conic_To( FT_Vector* control, - FT_Vector* to, - TBBox_Rec* user ) + FT_CALLBACK_DEF( int ) + BBox_Conic_To( const FT_Vector* control, + const FT_Vector* to, + void* user_ ) { + TBBox_Rec* user = (TBBox_Rec*)user_; + + /* in case `to' is implicit and not included in bbox yet */ FT_UPDATE_BBOX( to, user->bbox ); @@ -410,12 +419,15 @@ * In the case of a non-monotonous arc, we don't compute directly * extremum coordinates, we subdivide instead. */ - static int - BBox_Cubic_To( FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to, - TBBox_Rec* user ) + FT_CALLBACK_DEF( int ) + BBox_Cubic_To( const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to, + void* user_ ) { + TBBox_Rec* user = (TBBox_Rec*)user_; + + /* We don't need to check `to' since it is always an on-point, */ /* thus within the bbox. Only segments with an off-point outside */ /* the bbox can possibly reach new extreme values. */ diff --git a/thirdparty/freetype/src/base/ftcalc.c b/thirdparty/freetype/src/base/ftcalc.c index 13e74f3353..442b08ddf9 100644 --- a/thirdparty/freetype/src/base/ftcalc.c +++ b/thirdparty/freetype/src/base/ftcalc.c @@ -1061,7 +1061,7 @@ /* */ /* This approach has the advantage that the angle between */ /* `in' and `out' is not checked. In case one of the two */ - /* vectors is `dominant', this is, much larger than the */ + /* vectors is `dominant', that is, much larger than the */ /* other vector, we thus always have a flat corner. */ /* */ /* hypotenuse */ @@ -1103,7 +1103,7 @@ for ( i = 0; i < count; ++i ) temp += (FT_Int64)s[i] * f[i]; - return ( temp + 0x8000 ) >> 16; + return (FT_Int32)( ( temp + 0x8000 ) >> 16 ); #else temp.hi = 0; temp.lo = 0; diff --git a/thirdparty/freetype/src/base/ftdbgmem.c b/thirdparty/freetype/src/base/ftdbgmem.c index 6730c4c8d3..8fab50dd01 100644 --- a/thirdparty/freetype/src/base/ftdbgmem.c +++ b/thirdparty/freetype/src/base/ftdbgmem.c @@ -963,7 +963,7 @@ #else /* !FT_DEBUG_MEMORY */ /* ANSI C doesn't like empty source files */ - typedef int _debug_mem_dummy; + typedef int debug_mem_dummy_; #endif /* !FT_DEBUG_MEMORY */ diff --git a/thirdparty/freetype/src/base/ftmac.c b/thirdparty/freetype/src/base/ftmac.c index de34e834f2..492d055384 100644 --- a/thirdparty/freetype/src/base/ftmac.c +++ b/thirdparty/freetype/src/base/ftmac.c @@ -1082,7 +1082,7 @@ #else /* !FT_MACINTOSH */ /* ANSI C doesn't like empty source files */ - typedef int _ft_mac_dummy; + typedef int ft_mac_dummy_; #endif /* !FT_MACINTOSH */ diff --git a/thirdparty/freetype/src/base/ftmm.c b/thirdparty/freetype/src/base/ftmm.c index a2b4bd03d7..9e2dd7ee79 100644 --- a/thirdparty/freetype/src/base/ftmm.c +++ b/thirdparty/freetype/src/base/ftmm.c @@ -185,6 +185,14 @@ error = FT_ERR( Invalid_Argument ); if ( service->set_mm_design ) error = service->set_mm_design( face, num_coords, coords ); + + if ( !error ) + { + if ( num_coords ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + } } /* enforce recomputation of auto-hinting data */ @@ -220,6 +228,14 @@ error = FT_ERR( Invalid_Argument ); if ( service->set_mm_weightvector ) error = service->set_mm_weightvector( face, len, weightvector ); + + if ( !error ) + { + if ( len ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + } } /* enforce recomputation of auto-hinting data */ @@ -283,6 +299,30 @@ if ( service_mm->set_var_design ) error = service_mm->set_var_design( face, num_coords, coords ); + if ( !error || error == -1 ) + { + FT_Bool is_variation_old = FT_IS_VARIATION( face ); + + + if ( num_coords ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + + if ( service_mm->construct_ps_name ) + { + if ( error == -1 ) + { + /* The PS name of a named instance and a non-named instance */ + /* usually differs, even if the axis values are identical. */ + if ( is_variation_old != FT_IS_VARIATION( face ) ) + service_mm->construct_ps_name( face ); + } + else + service_mm->construct_ps_name( face ); + } + } + /* internal error code -1 means `no change'; we can exit immediately */ if ( error == -1 ) return FT_Err_Ok; @@ -359,6 +399,30 @@ if ( service_mm->set_mm_blend ) error = service_mm->set_mm_blend( face, num_coords, coords ); + if ( !error || error == -1 ) + { + FT_Bool is_variation_old = FT_IS_VARIATION( face ); + + + if ( num_coords ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + + if ( service_mm->construct_ps_name ) + { + if ( error == -1 ) + { + /* The PS name of a named instance and a non-named instance */ + /* usually differs, even if the axis values are identical. */ + if ( is_variation_old != FT_IS_VARIATION( face ) ) + service_mm->construct_ps_name( face ); + } + else + service_mm->construct_ps_name( face ); + } + } + /* internal error code -1 means `no change'; we can exit immediately */ if ( error == -1 ) return FT_Err_Ok; @@ -410,6 +474,30 @@ if ( service_mm->set_mm_blend ) error = service_mm->set_mm_blend( face, num_coords, coords ); + if ( !error || error == -1 ) + { + FT_Bool is_variation_old = FT_IS_VARIATION( face ); + + + if ( num_coords ) + face->face_flags |= FT_FACE_FLAG_VARIATION; + else + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + + if ( service_mm->construct_ps_name ) + { + if ( error == -1 ) + { + /* The PS name of a named instance and a non-named instance */ + /* usually differs, even if the axis values are identical. */ + if ( is_variation_old != FT_IS_VARIATION( face ) ) + service_mm->construct_ps_name( face ); + } + else + service_mm->construct_ps_name( face ); + } + } + /* internal error code -1 means `no change'; we can exit immediately */ if ( error == -1 ) return FT_Err_Ok; @@ -535,8 +623,35 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service_mm->set_instance ) - error = service_mm->set_instance( face, instance_index ); + if ( service_mm->set_named_instance ) + error = service_mm->set_named_instance( face, instance_index ); + + if ( !error || error == -1 ) + { + FT_Bool is_variation_old = FT_IS_VARIATION( face ); + + + face->face_flags &= ~FT_FACE_FLAG_VARIATION; + face->face_index = ( instance_index << 16 ) | + ( face->face_index & 0xFFFFL ); + + if ( service_mm->construct_ps_name ) + { + if ( error == -1 ) + { + /* The PS name of a named instance and a non-named instance */ + /* usually differs, even if the axis values are identical. */ + if ( is_variation_old != FT_IS_VARIATION( face ) ) + service_mm->construct_ps_name( face ); + } + else + service_mm->construct_ps_name( face ); + } + } + + /* internal error code -1 means `no change'; we can exit immediately */ + if ( error == -1 ) + return FT_Err_Ok; } if ( !error ) @@ -554,11 +669,32 @@ face->autohint.data = NULL; } + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Default_Named_Instance( FT_Face face, + FT_UInt *instance_index ) + { + FT_Error error; + + FT_Service_MultiMasters service_mm = NULL; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + error = ft_face_get_mm_service( face, &service_mm ); if ( !error ) { - face->face_index = ( instance_index << 16 ) | - ( face->face_index & 0xFFFFL ); - face->face_flags &= ~FT_FACE_FLAG_VARIATION; + /* no error if `get_default_named_instance` is not available */ + if ( service_mm->get_default_named_instance ) + error = service_mm->get_default_named_instance( face, + instance_index ); + else + error = FT_Err_Ok; } return error; diff --git a/thirdparty/freetype/src/base/ftobjs.c b/thirdparty/freetype/src/base/ftobjs.c index ad6ef0ae16..abfa3ab0e6 100644 --- a/thirdparty/freetype/src/base/ftobjs.c +++ b/thirdparty/freetype/src/base/ftobjs.c @@ -1019,7 +1019,8 @@ /* elegant. */ /* try to load SVG documents if available */ - if ( FT_HAS_SVG( face ) ) + if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 && + FT_HAS_SVG( face ) ) { error = driver->clazz->load_glyph( slot, face->size, glyph_index, @@ -1245,9 +1246,13 @@ /* destructor for sizes list */ static void destroy_size( FT_Memory memory, - FT_Size size, - FT_Driver driver ) + void* size_, + void* driver_ ) { + FT_Size size = (FT_Size)size_; + FT_Driver driver = (FT_Driver)driver_; + + /* finalize client-specific data */ if ( size->generic.finalizer ) size->generic.finalizer( size ); @@ -1293,10 +1298,12 @@ /* destructor for faces list */ static void destroy_face( FT_Memory memory, - FT_Face face, - FT_Driver driver ) + void* face_, + void* driver_ ) { - FT_Driver_Class clazz = driver->clazz; + FT_Face face = (FT_Face)face_; + FT_Driver driver = (FT_Driver)driver_; + FT_Driver_Class clazz = driver->clazz; /* discard auto-hinting data */ @@ -1310,7 +1317,7 @@ /* discard all sizes for this face */ FT_List_Finalize( &face->sizes_list, - (FT_List_Destructor)destroy_size, + destroy_size, memory, driver ); face->size = NULL; @@ -1346,7 +1353,7 @@ Destroy_Driver( FT_Driver driver ) { FT_List_Finalize( &driver->faces_list, - (FT_List_Destructor)destroy_face, + destroy_face, driver->root.memory, driver ); } diff --git a/thirdparty/freetype/src/base/ftoutln.c b/thirdparty/freetype/src/base/ftoutln.c index 30ff21ff39..134f39d2b1 100644 --- a/thirdparty/freetype/src/base/ftoutln.c +++ b/thirdparty/freetype/src/base/ftoutln.c @@ -58,7 +58,9 @@ FT_Error error; FT_Int n; /* index of contour in outline */ - FT_UInt first; /* index of first point in contour */ + FT_Int first; /* index of first point in contour */ + FT_Int last; /* index of last point in contour */ + FT_Int tag; /* current point's state */ FT_Int shift; @@ -73,18 +75,17 @@ shift = func_interface->shift; delta = func_interface->delta; - first = 0; + last = -1; for ( n = 0; n < outline->n_contours; n++ ) { - FT_Int last; /* index of last point in contour */ - - - FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + FT_TRACE5(( "FT_Outline_Decompose: Contour %d\n", n )); - last = outline->contours[n]; - if ( last < 0 ) + first = last + 1; + last = outline->contours[n]; + if ( last < first ) goto Invalid_Outline; + limit = outline->points + last; v_start = outline->points[first]; @@ -282,8 +283,6 @@ Close: if ( error ) goto Exit; - - first = (FT_UInt)last + 1; } FT_TRACE5(( "FT_Outline_Decompose: Done\n" )); @@ -368,7 +367,7 @@ if ( n_points <= 0 || n_contours <= 0 ) goto Bad; - end0 = end = -1; + end0 = -1; for ( n = 0; n < n_contours; n++ ) { end = outline->contours[n]; @@ -380,7 +379,7 @@ end0 = end; } - if ( end != n_points - 1 ) + if ( end0 != n_points - 1 ) goto Bad; /* XXX: check the tags array */ @@ -388,7 +387,7 @@ } Bad: - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Outline ); } @@ -550,10 +549,12 @@ if ( !outline ) return; - first = 0; - + last = -1; for ( n = 0; n < outline->n_contours; n++ ) { + /* keep the first contour point as is and swap points around it */ + /* to guarantee that the cubic arches stay valid after reverse */ + first = last + 2; last = outline->contours[n]; /* reverse point table */ @@ -591,8 +592,6 @@ q--; } } - - first = last + 1; } outline->flags ^= FT_OUTLINE_REVERSE_FILL; @@ -941,7 +940,7 @@ points = outline->points; - first = 0; + last = -1; for ( c = 0; c < outline->n_contours; c++ ) { FT_Vector in, out, anchor, shift; @@ -949,8 +948,9 @@ FT_Int i, j, k; - l_in = 0; - last = outline->contours[c]; + first = last + 1; + last = outline->contours[c]; + l_in = 0; /* pacify compiler */ in.x = in.y = anchor.x = anchor.y = 0; @@ -1037,8 +1037,6 @@ in = out; l_in = l_out; } - - first = last + 1; } return FT_Err_Ok; @@ -1054,7 +1052,7 @@ FT_Int xshift, yshift; FT_Vector* points; FT_Vector v_prev, v_cur; - FT_Int c, n, first; + FT_Int c, n, first, last; FT_Pos area = 0; @@ -1086,11 +1084,11 @@ points = outline->points; - first = 0; + last = -1; for ( c = 0; c < outline->n_contours; c++ ) { - FT_Int last = outline->contours[c]; - + first = last + 1; + last = outline->contours[c]; v_prev.x = points[last].x >> xshift; v_prev.y = points[last].y >> yshift; @@ -1106,8 +1104,6 @@ v_prev = v_cur; } - - first = last + 1; } if ( area > 0 ) diff --git a/thirdparty/freetype/src/base/ftstroke.c b/thirdparty/freetype/src/base/ftstroke.c index db358e772e..92f1e43080 100644 --- a/thirdparty/freetype/src/base/ftstroke.c +++ b/thirdparty/freetype/src/base/ftstroke.c @@ -2055,7 +2055,9 @@ FT_Error error; FT_Int n; /* index of contour in outline */ - FT_UInt first; /* index of first point in contour */ + FT_Int first; /* index of first point in contour */ + FT_Int last; /* index of last point in contour */ + FT_Int tag; /* current point's state */ @@ -2067,22 +2069,17 @@ FT_Stroker_Rewind( stroker ); - first = 0; - + last = -1; for ( n = 0; n < outline->n_contours; n++ ) { - FT_UInt last; /* index of last point in contour */ - - - last = (FT_UInt)outline->contours[n]; - limit = outline->points + last; + first = last + 1; + last = outline->contours[n]; /* skip empty points; we don't stroke these */ if ( last <= first ) - { - first = last + 1; continue; - } + + limit = outline->points + last; v_start = outline->points[first]; v_last = outline->points[last]; @@ -2231,8 +2228,6 @@ if ( error ) goto Exit; } - - first = last + 1; } return FT_Err_Ok; diff --git a/thirdparty/freetype/src/base/ftsynth.c b/thirdparty/freetype/src/base/ftsynth.c index 6ec25e13e4..f32edd3388 100644 --- a/thirdparty/freetype/src/base/ftsynth.c +++ b/thirdparty/freetype/src/base/ftsynth.c @@ -98,8 +98,17 @@ FT_EXPORT_DEF( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) { + FT_GlyphSlot_AdjustWeight( slot, 0x0AAA, 0x0AAA ); + } + + + FT_EXPORT_DEF( void ) + FT_GlyphSlot_AdjustWeight( FT_GlyphSlot slot, + FT_Fixed xdelta, + FT_Fixed ydelta ) + { FT_Library library; - FT_Face face; + FT_Size size; FT_Error error; FT_Pos xstr, ystr; @@ -108,16 +117,15 @@ return; library = slot->library; - face = slot->face; + size = slot->face->size; if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && slot->format != FT_GLYPH_FORMAT_BITMAP ) return; - /* some reasonable strength */ - xstr = FT_MulFix( face->units_per_EM, - face->size->metrics.y_scale ) / 24; - ystr = xstr; + /* express deltas in pixels in 26.6 format */ + xstr = (FT_Pos)size->metrics.x_ppem * xdelta / 1024; + ystr = (FT_Pos)size->metrics.y_ppem * ydelta / 1024; if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); diff --git a/thirdparty/freetype/src/base/ftsystem.c b/thirdparty/freetype/src/base/ftsystem.c index fcd289d19f..61c99e3635 100644 --- a/thirdparty/freetype/src/base/ftsystem.c +++ b/thirdparty/freetype/src/base/ftsystem.c @@ -206,7 +206,7 @@ * The number of bytes to read from the stream. * * @Return: - * The number of bytes actually read. If `count' is zero (this is, + * The number of bytes actually read. If `count' is zero (that is, * the function is used for seeking), a non-zero return value * indicates an error. */ @@ -219,7 +219,7 @@ FT_FILE* file; - if ( !count && offset > stream->size ) + if ( offset > stream->size && !count ) return 1; file = STREAM_FILE( stream ); @@ -227,6 +227,11 @@ if ( stream->pos != offset ) ft_fseek( file, (long)offset, SEEK_SET ); + /* Avoid calling `fread` with `buffer=NULL` and `count=0`, */ + /* which is undefined behaviour. */ + if ( !count ) + return 0; + return (unsigned long)ft_fread( buffer, 1, count, file ); } diff --git a/thirdparty/freetype/src/bdf/bdf.h b/thirdparty/freetype/src/bdf/bdf.h index 5acbd5f2f9..e2cb52c10a 100644 --- a/thirdparty/freetype/src/bdf/bdf.h +++ b/thirdparty/freetype/src/bdf/bdf.h @@ -240,10 +240,6 @@ FT_BEGIN_HEADER bdf_free_font( bdf_font_t* font ); FT_LOCAL( bdf_property_t * ) - bdf_get_property( char* name, - bdf_font_t* font ); - - FT_LOCAL( bdf_property_t * ) bdf_get_font_property( bdf_font_t* font, const char* name ); diff --git a/thirdparty/freetype/src/bdf/bdfdrivr.c b/thirdparty/freetype/src/bdf/bdfdrivr.c index d7e8e0efc5..e02a160930 100644 --- a/thirdparty/freetype/src/bdf/bdfdrivr.c +++ b/thirdparty/freetype/src/bdf/bdfdrivr.c @@ -311,9 +311,9 @@ THE SOFTWARE. FT_CALLBACK_DEF( void ) - BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */ + BDF_Face_Done( FT_Face face ) /* BDF_Face */ { - BDF_Face face = (BDF_Face)bdfface; + BDF_Face bdfface = (BDF_Face)face; FT_Memory memory; @@ -322,31 +322,31 @@ THE SOFTWARE. memory = FT_FACE_MEMORY( face ); - bdf_free_font( face->bdffont ); + bdf_free_font( bdfface->bdffont ); - FT_FREE( face->en_table ); + FT_FREE( bdfface->en_table ); - FT_FREE( face->charset_encoding ); - FT_FREE( face->charset_registry ); - FT_FREE( bdfface->family_name ); - FT_FREE( bdfface->style_name ); + FT_FREE( bdfface->charset_encoding ); + FT_FREE( bdfface->charset_registry ); + FT_FREE( face->family_name ); + FT_FREE( face->style_name ); - FT_FREE( bdfface->available_sizes ); + FT_FREE( face->available_sizes ); - FT_FREE( face->bdffont ); + FT_FREE( bdfface->bdffont ); } FT_CALLBACK_DEF( FT_Error ) BDF_Face_Init( FT_Stream stream, - FT_Face bdfface, /* BDF_Face */ + FT_Face face, /* BDF_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { - FT_Error error = FT_Err_Ok; - BDF_Face face = (BDF_Face)bdfface; - FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Error error = FT_Err_Ok; + BDF_Face bdfface = (BDF_Face)face; + FT_Memory memory = FT_FACE_MEMORY( face ); bdf_font_t* font = NULL; bdf_options_t options; @@ -375,7 +375,7 @@ THE SOFTWARE. goto Exit; /* we have a bdf font: let's construct the face object */ - face->bdffont = font; + bdfface->bdffont = font; /* BDF cannot have multiple faces in a single font file. * XXX: non-zero face_index is already invalid argument, but @@ -386,7 +386,7 @@ THE SOFTWARE. if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "BDF_Face_Init: invalid face index\n" )); - BDF_Face_Done( bdfface ); + BDF_Face_Done( face ); return FT_THROW( Invalid_Argument ); } @@ -401,18 +401,18 @@ THE SOFTWARE. font->unencoded_size, font->unencoded_used )); - bdfface->num_faces = 1; - bdfface->face_index = 0; + face->num_faces = 1; + face->face_index = 0; - bdfface->face_flags |= FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL; + face->face_flags |= FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL; prop = bdf_get_font_property( font, "SPACING" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' || *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) ) - bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + face->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ /* FZ XXX: I need a font to implement this */ @@ -420,26 +420,27 @@ THE SOFTWARE. prop = bdf_get_font_property( font, "FAMILY_NAME" ); if ( prop && prop->value.atom ) { - if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) ) + if ( FT_STRDUP( face->family_name, prop->value.atom ) ) goto Exit; } else - bdfface->family_name = NULL; + face->family_name = NULL; - if ( FT_SET_ERROR( bdf_interpret_style( face ) ) ) + if ( FT_SET_ERROR( bdf_interpret_style( bdfface ) ) ) goto Exit; /* the number of glyphs (with one slot for the undefined glyph */ /* at position 0 and all unencoded glyphs) */ - bdfface->num_glyphs = (FT_Long)( font->glyphs_size + 1 ); + face->num_glyphs = (FT_Long)( font->glyphs_size + 1 ); - bdfface->num_fixed_sizes = 1; - if ( FT_NEW( bdfface->available_sizes ) ) + face->num_fixed_sizes = 1; + if ( FT_NEW( face->available_sizes ) ) goto Exit; { - FT_Bitmap_Size* bsize = bdfface->available_sizes; - FT_Short resolution_x = 0, resolution_y = 0; + FT_Bitmap_Size* bsize = face->available_sizes; + FT_Short resolution_x = 0; + FT_Short resolution_y = 0; long value; @@ -598,20 +599,20 @@ THE SOFTWARE. unsigned long n; - if ( FT_QNEW_ARRAY( face->en_table, font->glyphs_size ) ) + if ( FT_QNEW_ARRAY( bdfface->en_table, font->glyphs_size ) ) goto Exit; - face->default_glyph = 0; + bdfface->default_glyph = 0; for ( n = 0; n < font->glyphs_size; n++ ) { - (face->en_table[n]).enc = cur[n].encoding; + (bdfface->en_table[n]).enc = cur[n].encoding; FT_TRACE4(( " idx %ld, val 0x%lX\n", n, cur[n].encoding )); - (face->en_table[n]).glyph = (FT_UShort)n; + (bdfface->en_table[n]).glyph = (FT_UShort)n; if ( cur[n].encoding == font->default_char ) { if ( n < FT_UINT_MAX ) - face->default_glyph = (FT_UInt)n; + bdfface->default_glyph = (FT_UInt)n; else FT_TRACE1(( "BDF_Face_Init:" " idx %ld is too large for this system\n", n )); @@ -639,27 +640,27 @@ THE SOFTWARE. const char* s; - if ( FT_STRDUP( face->charset_encoding, + if ( FT_STRDUP( bdfface->charset_encoding, charset_encoding->value.atom ) || - FT_STRDUP( face->charset_registry, + FT_STRDUP( bdfface->charset_registry, charset_registry->value.atom ) ) goto Exit; /* Uh, oh, compare first letters manually to avoid dependency */ /* on locales. */ - s = face->charset_registry; + s = bdfface->charset_registry; if ( ( s[0] == 'i' || s[0] == 'I' ) && ( s[1] == 's' || s[1] == 'S' ) && ( s[2] == 'o' || s[2] == 'O' ) ) { s += 3; - if ( !ft_strcmp( s, "10646" ) || - ( !ft_strcmp( s, "8859" ) && - !ft_strcmp( face->charset_encoding, "1" ) ) ) + if ( !ft_strcmp( s, "10646" ) || + ( !ft_strcmp( s, "8859" ) && + !ft_strcmp( bdfface->charset_encoding, "1" ) ) ) unicode_charmap = 1; /* another name for ASCII */ - else if ( !ft_strcmp( s, "646.1991" ) && - !ft_strcmp( face->charset_encoding, "IRV" ) ) + else if ( !ft_strcmp( s, "646.1991" ) && + !ft_strcmp( bdfface->charset_encoding, "IRV" ) ) unicode_charmap = 1; } @@ -667,7 +668,7 @@ THE SOFTWARE. FT_CharMapRec charmap; - charmap.face = FT_FACE( face ); + charmap.face = face; charmap.encoding = FT_ENCODING_NONE; /* initial platform/encoding should indicate unset status? */ charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; @@ -693,7 +694,7 @@ THE SOFTWARE. FT_CharMapRec charmap; - charmap.face = FT_FACE( face ); + charmap.face = face; charmap.encoding = FT_ENCODING_ADOBE_STANDARD; charmap.platform_id = TT_PLATFORM_ADOBE; charmap.encoding_id = TT_ADOBE_ID_STANDARD; @@ -701,8 +702,8 @@ THE SOFTWARE. error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); /* Select default charmap */ - if ( bdfface->num_charmaps ) - bdfface->charmap = bdfface->charmaps[0]; + if ( face->num_charmaps ) + face->charmap = face->charmaps[0]; } } } @@ -711,7 +712,7 @@ THE SOFTWARE. return error; Fail: - BDF_Face_Done( bdfface ); + BDF_Face_Done( face ); return FT_THROW( Unknown_File_Format ); } @@ -868,17 +869,18 @@ THE SOFTWARE. * */ - static FT_Error - bdf_get_bdf_property( BDF_Face face, + FT_CALLBACK_DEF( FT_Error ) + bdf_get_bdf_property( FT_Face face, /* BDF_Face */ const char* prop_name, BDF_PropertyRec *aproperty ) { + BDF_Face bdfface = (BDF_Face)face; bdf_property_t* prop; - FT_ASSERT( face && face->bdffont ); + FT_ASSERT( bdfface && bdfface->bdffont ); - prop = bdf_get_font_property( face->bdffont, prop_name ); + prop = bdf_get_font_property( bdfface->bdffont, prop_name ); if ( prop ) { switch ( prop->format ) @@ -921,13 +923,16 @@ THE SOFTWARE. } - static FT_Error - bdf_get_charset_id( BDF_Face face, + FT_CALLBACK_DEF( FT_Error ) + bdf_get_charset_id( FT_Face face, /* BDF_Face */ const char* *acharset_encoding, const char* *acharset_registry ) { - *acharset_encoding = face->charset_encoding; - *acharset_registry = face->charset_registry; + BDF_Face bdfface = (BDF_Face)face; + + + *acharset_encoding = bdfface->charset_encoding; + *acharset_registry = bdfface->charset_registry; return 0; } @@ -964,7 +969,6 @@ THE SOFTWARE. } - FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec bdf_driver_class = { diff --git a/thirdparty/freetype/src/bdf/bdflib.c b/thirdparty/freetype/src/bdf/bdflib.c index 2224698fc0..0fa7e0a8c5 100644 --- a/thirdparty/freetype/src/bdf/bdflib.c +++ b/thirdparty/freetype/src/bdf/bdflib.c @@ -51,6 +51,9 @@ #define FT_COMPONENT bdflib +#define BUFSIZE 128 + + /************************************************************************** * * Default BDF font options. @@ -378,7 +381,7 @@ *alen = 0; if ( list == NULL || list->used == 0 ) - return 0; + return NULL; dp = list->field[0]; for ( i = j = 0; i < list->used; i++ ) @@ -887,18 +890,18 @@ } - FT_LOCAL_DEF( bdf_property_t* ) - bdf_get_property( char* name, + static bdf_property_t* + bdf_get_property( const char* name, bdf_font_t* font ) { size_t* propid; if ( name == NULL || *name == 0 ) - return 0; + return NULL; if ( ( propid = ft_hash_str_lookup( name, &(font->proptbl) ) ) == NULL ) - return 0; + return NULL; if ( *propid >= num_bdf_properties_ ) return font->user_props + ( *propid - num_bdf_properties_ ); @@ -944,7 +947,7 @@ static FT_Error bdf_add_comment_( bdf_font_t* font, - char* comment, + const char* comment, unsigned long len ) { char* cp; @@ -1053,27 +1056,24 @@ bdf_property_t* p; - *name = sp = ep = line; + sp = ep = line; while ( *ep && *ep != ' ' && *ep != '\t' ) ep++; - hold = -1; - if ( *ep ) - { - hold = *ep; - *ep = 0; - } + hold = *ep; + *ep = '\0'; p = bdf_get_property( sp, font ); - /* Restore the character that was saved before any return can happen. */ - if ( hold != -1 ) - *ep = (char)hold; - /* If the property exists and is not an atom, just return here. */ if ( p && p->format != BDF_ATOM ) + { + *ep = (char)hold; /* Undo NUL-termination. */ return 0; + } + + *name = sp; /* The property is an atom. Trim all leading and trailing whitespace */ /* and double quotes for the atom value. */ @@ -1081,25 +1081,26 @@ ep = line + linelen; /* Trim the leading whitespace if it exists. */ - if ( *sp ) - *sp++ = 0; - while ( *sp && - ( *sp == ' ' || *sp == '\t' ) ) - sp++; + if ( sp < ep ) + do + sp++; + while ( *sp == ' ' || *sp == '\t' ); /* Trim the leading double quote if it exists. */ if ( *sp == '"' ) sp++; + *value = sp; /* Trim the trailing whitespace if it exists. */ - while ( ep > sp && - ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) ) - *--ep = 0; + if ( sp < ep ) + do + *ep-- = '\0'; + while ( *ep == ' ' || *ep == '\t' ); /* Trim the trailing double quote if it exists. */ - if ( ep > sp && *( ep - 1 ) == '"' ) - *--ep = 0; + if ( *ep == '"' ) + *ep = '\0'; return 1; } @@ -1775,7 +1776,7 @@ bdf_parse_t_* p; char* name; char* value; - char nbuf[128]; + char nbuf[BUFSIZE]; FT_Error error = FT_Err_Ok; FT_UNUSED( lineno ); @@ -1796,7 +1797,7 @@ if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 ) { p->font->font_ascent = p->font->bbx.ascent; - ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); + ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.ascent ); error = bdf_add_property_( p->font, "FONT_ASCENT", nbuf, lineno ); if ( error ) @@ -1808,7 +1809,7 @@ if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 ) { p->font->font_descent = p->font->bbx.descent; - ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); + ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.descent ); error = bdf_add_property_( p->font, "FONT_DESCENT", nbuf, lineno ); if ( error ) @@ -2116,7 +2117,7 @@ /* Check for the CHARS field -- font properties are optional */ if ( _bdf_strncmp( line, "CHARS", 5 ) == 0 ) { - char nbuf[128]; + char nbuf[BUFSIZE]; if ( !( p->flags & BDF_FONT_BBX_ ) ) @@ -2130,7 +2131,7 @@ /* Add the two standard X11 properties which are required */ /* for compiling fonts. */ p->font->font_ascent = p->font->bbx.ascent; - ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); + ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.ascent ); error = bdf_add_property_( p->font, "FONT_ASCENT", nbuf, lineno ); if ( error ) @@ -2138,7 +2139,7 @@ FT_TRACE2(( "bdf_parse_properties_: " ACMSG1, p->font->bbx.ascent )); p->font->font_descent = p->font->bbx.descent; - ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); + ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.descent ); error = bdf_add_property_( p->font, "FONT_DESCENT", nbuf, lineno ); if ( error ) diff --git a/thirdparty/freetype/src/bzip2/ftbzip2.c b/thirdparty/freetype/src/bzip2/ftbzip2.c index 6cf10678b7..ad342bd011 100644 --- a/thirdparty/freetype/src/bzip2/ftbzip2.c +++ b/thirdparty/freetype/src/bzip2/ftbzip2.c @@ -62,10 +62,12 @@ static void* - ft_bzip2_alloc( FT_Memory memory, - int items, - int size ) + ft_bzip2_alloc( void* memory_, /* FT_Memory */ + int items, + int size ) { + FT_Memory memory = (FT_Memory)memory_; + FT_ULong sz = (FT_ULong)size * (FT_ULong)items; FT_Error error; FT_Pointer p = NULL; @@ -77,9 +79,12 @@ static void - ft_bzip2_free( FT_Memory memory, - void* address ) + ft_bzip2_free( void* memory_, /* FT_Memory */ + void* address ) { + FT_Memory memory = (FT_Memory)memory_; + + FT_MEM_FREE( address ); } @@ -170,8 +175,8 @@ } /* initialize bzlib */ - bzstream->bzalloc = (alloc_func)ft_bzip2_alloc; - bzstream->bzfree = (free_func) ft_bzip2_free; + bzstream->bzalloc = ft_bzip2_alloc; + bzstream->bzfree = ft_bzip2_free; bzstream->opaque = zip->memory; bzstream->avail_in = 0; diff --git a/thirdparty/freetype/src/cache/ftcbasic.c b/thirdparty/freetype/src/cache/ftcbasic.c index 4c6d41b2cd..24a56c8d26 100644 --- a/thirdparty/freetype/src/cache/ftcbasic.c +++ b/thirdparty/freetype/src/cache/ftcbasic.c @@ -337,7 +337,7 @@ #if 1 /* inlining is about 50% faster! */ FTC_GCACHE_LOOKUP_CMP( cache, ftc_basic_family_compare, - FTC_GNode_Compare, + ftc_gnode_compare, hash, gindex, &query, node, @@ -411,7 +411,7 @@ FTC_GCACHE_LOOKUP_CMP( cache, ftc_basic_family_compare, - FTC_GNode_Compare, + ftc_gnode_compare, hash, gindex, &query, node, @@ -537,7 +537,7 @@ #if 1 /* inlining is about 50% faster! */ FTC_GCACHE_LOOKUP_CMP( cache, ftc_basic_family_compare, - FTC_SNode_Compare, + ftc_snode_compare, hash, gindex, &query, node, @@ -613,7 +613,7 @@ FTC_GCACHE_LOOKUP_CMP( cache, ftc_basic_family_compare, - FTC_SNode_Compare, + ftc_snode_compare, hash, gindex, &query, node, diff --git a/thirdparty/freetype/src/cache/ftccache.c b/thirdparty/freetype/src/cache/ftccache.c index d54e68ca9a..e0698557b7 100644 --- a/thirdparty/freetype/src/cache/ftccache.c +++ b/thirdparty/freetype/src/cache/ftccache.c @@ -94,8 +94,8 @@ idx = hash & cache->mask; - if ( idx < cache->p ) - idx = hash & ( 2 * cache->mask + 1 ); + if ( idx >= cache->p ) + idx = hash & ( cache->mask >> 1 ); return cache->buckets + idx; } @@ -113,9 +113,9 @@ for (;;) { FTC_Node node, *pnode; - FT_UFast p = cache->p; - FT_UFast mask = cache->mask; - FT_UFast count = mask + p + 1; /* number of buckets */ + FT_UFast p = cache->p; + FT_UFast size = cache->mask + 1; /* available size */ + FT_UFast half = size >> 1; /* do we need to expand the buckets array? */ @@ -127,20 +127,22 @@ /* try to expand the buckets array _before_ splitting * the bucket lists */ - if ( p >= mask ) + if ( p == size ) { FT_Memory memory = cache->memory; FT_Error error; /* if we can't expand the array, leave immediately */ - if ( FT_RENEW_ARRAY( cache->buckets, - ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) ) + if ( FT_QRENEW_ARRAY( cache->buckets, size, size * 2 ) ) break; + + cache->mask = 2 * size - 1; + half = size; } - /* split a single bucket */ - pnode = cache->buckets + p; + /* the bucket to split */ + pnode = cache->buckets + p - half; for (;;) { @@ -148,7 +150,7 @@ if ( !node ) break; - if ( node->hash & ( mask + 1 ) ) + if ( node->hash & half ) { *pnode = node->link; node->link = new_list; @@ -158,56 +160,50 @@ pnode = &node->link; } - cache->buckets[p + mask + 1] = new_list; + cache->buckets[p] = new_list; cache->slack += FTC_HASH_MAX_LOAD; + cache->p = p + 1; - if ( p >= mask ) - { - cache->mask = 2 * mask + 1; - cache->p = 0; - } - else - cache->p = p + 1; + FT_TRACE2(( "ftc_cache_resize: cache %u increased to %u hashes\n", + cache->index, cache->p )); } /* do we need to shrink the buckets array? */ - else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) + else if ( cache->slack > (FT_Long)p * FTC_HASH_SUB_LOAD ) { - FT_UFast old_index = p + mask; - FTC_Node* pold; + FTC_Node old_list = cache->buckets[--p]; - if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE ) + if ( p < FTC_HASH_INITIAL_SIZE ) break; - if ( p == 0 ) + if ( p == half ) { FT_Memory memory = cache->memory; FT_Error error; /* if we can't shrink the array, leave immediately */ - if ( FT_QRENEW_ARRAY( cache->buckets, - ( mask + 1 ) * 2, mask + 1 ) ) + if ( FT_QRENEW_ARRAY( cache->buckets, size, half ) ) break; - cache->mask >>= 1; - p = cache->mask; + cache->mask = half - 1; } - else - p--; - pnode = cache->buckets + p; + /* the bucket to merge */ + pnode = cache->buckets + p - half; + while ( *pnode ) pnode = &(*pnode)->link; - pold = cache->buckets + old_index; - *pnode = *pold; - *pold = NULL; + *pnode = old_list; cache->slack -= FTC_HASH_MAX_LOAD; cache->p = p; + + FT_TRACE2(( "ftc_cache_resize: cache %u decreased to %u hashes\n", + cache->index, cache->p )); } /* otherwise, the hash table is balanced */ @@ -239,7 +235,7 @@ if ( node == node0 ) break; - pnode = &(*pnode)->link; + pnode = &node->link; } *pnode = node0->link; @@ -323,40 +319,41 @@ FT_LOCAL_DEF( FT_Error ) - FTC_Cache_Init( FTC_Cache cache ) - { - return ftc_cache_init( cache ); - } - - - FT_LOCAL_DEF( FT_Error ) ftc_cache_init( FTC_Cache cache ) { FT_Memory memory = cache->memory; FT_Error error; - cache->p = 0; + cache->p = FTC_HASH_INITIAL_SIZE; cache->mask = FTC_HASH_INITIAL_SIZE - 1; cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; - FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ); + FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE ); return error; } - static void - FTC_Cache_Clear( FTC_Cache cache ) + FT_LOCAL_DEF( FT_Error ) + FTC_Cache_Init( FTC_Cache cache ) { - if ( cache && cache->buckets ) + return ftc_cache_init( cache ); + } + + + FT_LOCAL_DEF( void ) + ftc_cache_done( FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + + + if ( cache->buckets ) { FTC_Manager manager = cache->manager; + FT_UFast count = cache->p; FT_UFast i; - FT_UFast count; - count = cache->p + cache->mask + 1; - for ( i = 0; i < count; i++ ) { FTC_Node node = cache->buckets[i], next; @@ -376,30 +373,14 @@ cache->clazz.node_free( node, cache ); node = next; } - cache->buckets[i] = NULL; } - ftc_cache_resize( cache ); } - } + FT_FREE( cache->buckets ); - FT_LOCAL_DEF( void ) - ftc_cache_done( FTC_Cache cache ) - { - if ( cache->memory ) - { - FT_Memory memory = cache->memory; - - - FTC_Cache_Clear( cache ); - - FT_FREE( cache->buckets ); - cache->mask = 0; - cache->p = 0; - cache->slack = 0; - - cache->memory = NULL; - } + cache->p = 0; + cache->mask = 0; + cache->slack = 0; } @@ -562,12 +543,12 @@ FTC_Cache_RemoveFaceID( FTC_Cache cache, FTC_FaceID face_id ) { - FT_UFast i, count; FTC_Manager manager = cache->manager; FTC_Node frees = NULL; + FT_UFast count = cache->p; + FT_UFast i; - count = cache->p + cache->mask + 1; for ( i = 0; i < count; i++ ) { FTC_Node* pnode = cache->buckets + i; diff --git a/thirdparty/freetype/src/cache/ftccache.h b/thirdparty/freetype/src/cache/ftccache.h index 23bcb65858..850d2554b5 100644 --- a/thirdparty/freetype/src/cache/ftccache.h +++ b/thirdparty/freetype/src/cache/ftccache.h @@ -72,11 +72,12 @@ FT_BEGIN_HEADER #define FTC_NODE_NEXT( x ) FTC_NODE( (x)->mru.next ) #define FTC_NODE_PREV( x ) FTC_NODE( (x)->mru.prev ) + /* address the hash table entries */ #ifdef FTC_INLINE -#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \ - ( ( cache )->buckets + \ - ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \ - ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \ +#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \ + ( ( cache )->buckets + \ + ( ( ( ( hash ) & ( cache )->mask ) >= ( cache )->p ) \ + ? ( ( hash ) & ( ( cache )->mask >> 1 ) ) \ : ( ( hash ) & ( cache )->mask ) ) ) #else FT_LOCAL( FTC_Node* ) @@ -139,11 +140,13 @@ FT_BEGIN_HEADER } FTC_CacheClassRec; - /* each cache really implements a dynamic hash table to manage its nodes */ + /* each cache really implements a hash table to manage its nodes */ + /* the number of the table entries (buckets) can change dynamically */ + /* each bucket contains a linked lists of nodes for a given hash */ typedef struct FTC_CacheRec_ { - FT_UFast p; - FT_UFast mask; + FT_UFast p; /* hash table counter */ + FT_UFast mask; /* hash table index range */ FT_Long slack; FTC_Node* buckets; diff --git a/thirdparty/freetype/src/cache/ftcglyph.c b/thirdparty/freetype/src/cache/ftcglyph.c index b3fb2f219c..d344733f37 100644 --- a/thirdparty/freetype/src/cache/ftcglyph.c +++ b/thirdparty/freetype/src/cache/ftcglyph.c @@ -79,20 +79,6 @@ } -#ifdef FTC_INLINE - - FT_LOCAL_DEF( FT_Bool ) - FTC_GNode_Compare( FTC_GNode gnode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - return ftc_gnode_compare( FTC_NODE( gnode ), gquery, - cache, list_changed ); - } - -#endif - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -115,22 +101,22 @@ FT_LOCAL_DEF( FT_Error ) - ftc_gcache_init( FTC_Cache ftccache ) + ftc_gcache_init( FTC_Cache cache ) { - FTC_GCache cache = (FTC_GCache)ftccache; + FTC_GCache gcache = (FTC_GCache)cache; FT_Error error; - error = FTC_Cache_Init( FTC_CACHE( cache ) ); + error = FTC_Cache_Init( cache ); if ( !error ) { - FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; + FTC_GCacheClass clazz = (FTC_GCacheClass)cache->org_class; - FTC_MruList_Init( &cache->families, + FTC_MruList_Init( &gcache->families, clazz->family_class, 0, /* no maximum here! */ cache, - FTC_CACHE( cache )->memory ); + cache->memory ); } return error; @@ -140,31 +126,31 @@ #if 0 FT_LOCAL_DEF( FT_Error ) - FTC_GCache_Init( FTC_GCache cache ) + FTC_GCache_Init( FTC_GCache gcache ) { - return ftc_gcache_init( FTC_CACHE( cache ) ); + return ftc_gcache_init( FTC_CACHE( gcache ) ); } #endif /* 0 */ FT_LOCAL_DEF( void ) - ftc_gcache_done( FTC_Cache ftccache ) + ftc_gcache_done( FTC_Cache cache ) { - FTC_GCache cache = (FTC_GCache)ftccache; + FTC_GCache gcache = (FTC_GCache)cache; - FTC_Cache_Done( (FTC_Cache)cache ); - FTC_MruList_Done( &cache->families ); + FTC_Cache_Done( cache ); + FTC_MruList_Done( &gcache->families ); } #if 0 FT_LOCAL_DEF( void ) - FTC_GCache_Done( FTC_GCache cache ) + FTC_GCache_Done( FTC_GCache gcache ) { - ftc_gcache_done( FTC_CACHE( cache ) ); + ftc_gcache_done( FTC_CACHE( gcache ) ); } #endif /* 0 */ @@ -183,7 +169,7 @@ #ifndef FTC_INLINE FT_LOCAL_DEF( FT_Error ) - FTC_GCache_Lookup( FTC_GCache cache, + FTC_GCache_Lookup( FTC_GCache gcache, FT_Offset hash, FT_UInt gindex, FTC_GQuery query, @@ -204,7 +190,7 @@ /* out-of-memory condition occurs during glyph node initialization. */ family->num_nodes++; - error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); + error = FTC_Cache_Lookup( FTC_CACHE( gcache ), hash, query, anode ); if ( --family->num_nodes == 0 ) FTC_FAMILY_FREE( family, cache ); diff --git a/thirdparty/freetype/src/cache/ftcglyph.h b/thirdparty/freetype/src/cache/ftcglyph.h index 728d4db1d6..0181e98166 100644 --- a/thirdparty/freetype/src/cache/ftcglyph.h +++ b/thirdparty/freetype/src/cache/ftcglyph.h @@ -58,7 +58,7 @@ * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: * my_node_new (must call FTC_GNode_Init) * my_node_free (must call FTC_GNode_Done) - * my_node_compare (must call FTC_GNode_Compare) + * my_node_compare (must call ftc_gnode_compare) * my_node_remove_faceid (must call ftc_gnode_unselect in case * of match) * @@ -179,19 +179,6 @@ FT_BEGIN_HEADER FT_UInt gindex, /* glyph index for node */ FTC_Family family ); -#ifdef FTC_INLINE - - /* returns TRUE iff the query's glyph index correspond to the node; */ - /* this assumes that the `family' and `hash' fields of the query are */ - /* already correctly set */ - FT_LOCAL( FT_Bool ) - FTC_GNode_Compare( FTC_GNode gnode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed ); - -#endif - /* call this function to clear a node's family -- this is necessary */ /* to implement the `node_remove_faceid' cache method correctly */ FT_LOCAL( void ) diff --git a/thirdparty/freetype/src/cache/ftcmanag.c b/thirdparty/freetype/src/cache/ftcmanag.c index 6c84339100..94f8469c92 100644 --- a/thirdparty/freetype/src/cache/ftcmanag.c +++ b/thirdparty/freetype/src/cache/ftcmanag.c @@ -426,7 +426,7 @@ memory = manager->memory; /* now discard all caches */ - for (idx = manager->num_caches; idx-- > 0; ) + for ( idx = manager->num_caches; idx-- > 0; ) { FTC_Cache cache = manager->caches[idx]; @@ -537,7 +537,7 @@ FT_LOCAL_DEF( void ) FTC_Manager_Compress( FTC_Manager manager ) { - FTC_Node node, first; + FTC_Node node, prev, first; if ( !manager ) @@ -557,20 +557,16 @@ return; /* go to last node -- it's a circular list */ - node = FTC_NODE_PREV( first ); + prev = FTC_NODE_PREV( first ); do { - FTC_Node prev; - - - prev = ( node == first ) ? NULL : FTC_NODE_PREV( node ); + node = prev; + prev = FTC_NODE_PREV( node ); if ( node->ref_count <= 0 ) ftc_node_destroy( node, manager ); - node = prev; - - } while ( node && manager->cur_weight > manager->max_weight ); + } while ( node != first && manager->cur_weight > manager->max_weight ); } @@ -633,20 +629,20 @@ FT_UInt count ) { FTC_Node first = manager->nodes_list; - FTC_Node node; - FT_UInt result; + FTC_Node prev, node; + FT_UInt result = 0; /* try to remove `count' nodes from the list */ - if ( !first ) /* empty list! */ - return 0; + if ( !first || !count ) + return result; - /* go to last node - it's a circular list */ - node = FTC_NODE_PREV(first); - for ( result = 0; result < count; ) + /* go to last node -- it's a circular list */ + prev = FTC_NODE_PREV( first ); + do { - FTC_Node prev = FTC_NODE_PREV( node ); - + node = prev; + prev = FTC_NODE_PREV( node ); /* don't touch locked nodes */ if ( node->ref_count <= 0 ) @@ -654,13 +650,9 @@ ftc_node_destroy( node, manager ); result++; } + } while ( node != first && result < count ); - if ( node == first ) - break; - - node = prev; - } - return result; + return result; } diff --git a/thirdparty/freetype/src/cache/ftcmru.c b/thirdparty/freetype/src/cache/ftcmru.c index 67227033e7..ad10a06bc4 100644 --- a/thirdparty/freetype/src/cache/ftcmru.c +++ b/thirdparty/freetype/src/cache/ftcmru.c @@ -329,29 +329,23 @@ FTC_MruNode_CompareFunc selection, FT_Pointer key ) { - FTC_MruNode first, node, next; + FTC_MruNode first = list->nodes; + FTC_MruNode prev, node; - first = list->nodes; - while ( first && ( !selection || selection( first, key ) ) ) - { - FTC_MruList_Remove( list, first ); - first = list->nodes; - } + if ( !first || !selection ) + return; - if ( first ) + prev = first->prev; + do { - node = first->next; - while ( node != first ) - { - next = node->next; + node = prev; + prev = node->prev; - if ( selection( node, key ) ) - FTC_MruList_Remove( list, node ); + if ( selection( node, key ) ) + FTC_MruList_Remove( list, node ); - node = next; - } - } + } while ( node != first ); } diff --git a/thirdparty/freetype/src/cache/ftcsbits.c b/thirdparty/freetype/src/cache/ftcsbits.c index ee9dab2632..9929a0bcc3 100644 --- a/thirdparty/freetype/src/cache/ftcsbits.c +++ b/thirdparty/freetype/src/cache/ftcsbits.c @@ -342,7 +342,7 @@ FT_Bool result; - if (list_changed) + if ( list_changed ) *list_changed = FALSE; result = FT_BOOL( gnode->family == gquery->family && gindex - gnode->gindex < snode->count ); @@ -411,19 +411,4 @@ return result; } - -#ifdef FTC_INLINE - - FT_LOCAL_DEF( FT_Bool ) - FTC_SNode_Compare( FTC_SNode snode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed ) - { - return ftc_snode_compare( FTC_NODE( snode ), gquery, - cache, list_changed ); - } - -#endif - /* END */ diff --git a/thirdparty/freetype/src/cache/ftcsbits.h b/thirdparty/freetype/src/cache/ftcsbits.h index 3473923f03..e833cb5c30 100644 --- a/thirdparty/freetype/src/cache/ftcsbits.h +++ b/thirdparty/freetype/src/cache/ftcsbits.h @@ -81,17 +81,6 @@ FT_BEGIN_HEADER FTC_SNode_Weight( FTC_SNode inode ); #endif - -#ifdef FTC_INLINE - - FT_LOCAL( FT_Bool ) - FTC_SNode_Compare( FTC_SNode snode, - FTC_GQuery gquery, - FTC_Cache cache, - FT_Bool* list_changed); - -#endif - /* */ FT_END_HEADER diff --git a/thirdparty/freetype/src/cff/cffcmap.c b/thirdparty/freetype/src/cff/cffcmap.c index 6ed3143222..10d287bc81 100644 --- a/thirdparty/freetype/src/cff/cffcmap.c +++ b/thirdparty/freetype/src/cff/cffcmap.c @@ -32,9 +32,10 @@ /*************************************************************************/ FT_CALLBACK_DEF( FT_Error ) - cff_cmap_encoding_init( CFF_CMapStd cmap, - FT_Pointer pointer ) + cff_cmap_encoding_init( FT_CMap cmap, + FT_Pointer pointer ) { + CFF_CMapStd cffcmap = (CFF_CMapStd)cmap; TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); CFF_Font cff = (CFF_Font)face->extra.data; CFF_Encoding encoding = &cff->encoding; @@ -42,63 +43,56 @@ FT_UNUSED( pointer ); - cmap->gids = encoding->codes; + cffcmap->gids = encoding->codes; return 0; } FT_CALLBACK_DEF( void ) - cff_cmap_encoding_done( CFF_CMapStd cmap ) + cff_cmap_encoding_done( FT_CMap cmap ) { - cmap->gids = NULL; + CFF_CMapStd cffcmap = (CFF_CMapStd)cmap; + + + cffcmap->gids = NULL; } FT_CALLBACK_DEF( FT_UInt ) - cff_cmap_encoding_char_index( CFF_CMapStd cmap, - FT_UInt32 char_code ) + cff_cmap_encoding_char_index( FT_CMap cmap, + FT_UInt32 char_code ) { - FT_UInt result = 0; + CFF_CMapStd cffcmap = (CFF_CMapStd)cmap; + FT_UInt result = 0; if ( char_code < 256 ) - result = cmap->gids[char_code]; + result = cffcmap->gids[char_code]; return result; } - FT_CALLBACK_DEF( FT_UInt32 ) - cff_cmap_encoding_char_next( CFF_CMapStd cmap, - FT_UInt32 *pchar_code ) + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_encoding_char_next( FT_CMap cmap, + FT_UInt32 *pchar_code ) { - FT_UInt result = 0; - FT_UInt32 char_code = *pchar_code; + CFF_CMapStd cffcmap = (CFF_CMapStd)cmap; + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code; - *pchar_code = 0; - - if ( char_code < 255 ) + while ( char_code < 255 ) { - FT_UInt code = (FT_UInt)( char_code + 1 ); - - - for (;;) + result = cffcmap->gids[++char_code]; + if ( result ) { - if ( code >= 256 ) - break; - - result = cmap->gids[code]; - if ( result != 0 ) - { - *pchar_code = code; - break; - } - - code++; + *pchar_code = char_code; + break; } } + return result; } @@ -130,9 +124,10 @@ /*************************************************************************/ FT_CALLBACK_DEF( const char* ) - cff_sid_to_glyph_name( TT_Face face, + cff_sid_to_glyph_name( void* face_, /* TT_Face */ FT_UInt idx ) { + TT_Face face = (TT_Face)face_; CFF_Font cff = (CFF_Font)face->extra.data; CFF_Charset charset = &cff->charset; FT_UInt sid = charset->sids[idx]; @@ -143,14 +138,15 @@ FT_CALLBACK_DEF( FT_Error ) - cff_cmap_unicode_init( PS_Unicodes unicodes, + cff_cmap_unicode_init( FT_CMap cmap, /* PS_Unicodes */ FT_Pointer pointer ) { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); - CFF_Font cff = (CFF_Font)face->extra.data; - CFF_Charset charset = &cff->charset; - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Charset charset = &cff->charset; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; FT_UNUSED( pointer ); @@ -166,17 +162,18 @@ return psnames->unicodes_init( memory, unicodes, cff->num_glyphs, - (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name, + &cff_sid_to_glyph_name, (PS_FreeGlyphNameFunc)NULL, (FT_Pointer)face ); } FT_CALLBACK_DEF( void ) - cff_cmap_unicode_done( PS_Unicodes unicodes ) + cff_cmap_unicode_done( FT_CMap cmap ) /* PS_Unicodes */ { - FT_Face face = FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); + PS_Unicodes unicodes = (PS_Unicodes)cmap; + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( unicodes->maps ); @@ -185,25 +182,27 @@ FT_CALLBACK_DEF( FT_UInt ) - cff_cmap_unicode_char_index( PS_Unicodes unicodes, - FT_UInt32 char_code ) + cff_cmap_unicode_char_index( FT_CMap cmap, /* PS_Unicodes */ + FT_UInt32 char_code ) { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - CFF_Font cff = (CFF_Font)face->extra.data; - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; return psnames->unicodes_char_index( unicodes, char_code ); } - FT_CALLBACK_DEF( FT_UInt32 ) - cff_cmap_unicode_char_next( PS_Unicodes unicodes, - FT_UInt32 *pchar_code ) + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_unicode_char_next( FT_CMap cmap, /* PS_Unicodes */ + FT_UInt32 *pchar_code ) { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - CFF_Font cff = (CFF_Font)face->extra.data; - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; return psnames->unicodes_char_next( unicodes, pchar_code ); diff --git a/thirdparty/freetype/src/cff/cffdrivr.c b/thirdparty/freetype/src/cff/cffdrivr.c index 4e2e0e00de..9898d625ca 100644 --- a/thirdparty/freetype/src/cff/cffdrivr.c +++ b/thirdparty/freetype/src/cff/cffdrivr.c @@ -108,20 +108,20 @@ * They can be implemented by format-specific interfaces. */ FT_CALLBACK_DEF( FT_Error ) - cff_get_kerning( FT_Face ttface, /* TT_Face */ + cff_get_kerning( FT_Face face, /* CFF_Face */ FT_UInt left_glyph, FT_UInt right_glyph, FT_Vector* kerning ) { - TT_Face face = (TT_Face)ttface; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + CFF_Face cffface = (CFF_Face)face; + SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; kerning->x = 0; kerning->y = 0; if ( sfnt ) - kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); + kerning->x = sfnt->get_kerning( cffface, left_glyph, right_glyph ); return FT_Err_Ok; } @@ -158,23 +158,23 @@ * FreeType error code. 0 means success. */ FT_CALLBACK_DEF( FT_Error ) - cff_glyph_load( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ - FT_Size cffsize, /* CFF_Size */ + cff_glyph_load( FT_GlyphSlot slot, /* CFF_GlyphSlot */ + FT_Size size, /* CFF_Size */ FT_UInt glyph_index, FT_Int32 load_flags ) { FT_Error error; - CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; - CFF_Size size = (CFF_Size)cffsize; + CFF_GlyphSlot cffslot = (CFF_GlyphSlot)slot; + CFF_Size cffsize = (CFF_Size)size; - if ( !slot ) + if ( !cffslot ) return FT_THROW( Invalid_Slot_Handle ); FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index )); /* check whether we want a scaled outline or bitmap */ - if ( !size ) + if ( !cffsize ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; /* reset the size object if necessary */ @@ -184,12 +184,12 @@ if ( size ) { /* these two objects must have the same parent */ - if ( cffsize->face != cffslot->face ) + if ( size->face != slot->face ) return FT_THROW( Invalid_Face_Handle ); } /* now load the glyph outline if necessary */ - error = cff_slot_load( slot, size, glyph_index, load_flags ); + error = cff_slot_load( cffslot, cffsize, glyph_index, load_flags ); /* force drop-out mode to 2 - irrelevant now */ /* slot->outline.dropout_mode = 2; */ @@ -216,7 +216,7 @@ /* it is no longer necessary that those values are identical to */ /* the values in the `CFF' table */ - TT_Face ttface = (TT_Face)face; + CFF_Face cffface = (CFF_Face)face; FT_Short dummy; @@ -225,7 +225,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* no fast retrieval for blended MM fonts without VVAR table */ if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && - !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + !( cffface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) return FT_THROW( Unimplemented_Feature ); #endif @@ -233,7 +233,7 @@ /* otherwise we extract the info from the CFF glyphstrings */ /* (instead of synthesizing a global value using the `OS/2' */ /* table) */ - if ( !ttface->vertical_info ) + if ( !cffface->vertical_info ) goto Missing_Table; for ( nn = 0; nn < count; nn++ ) @@ -241,11 +241,11 @@ FT_UShort ah; - ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, - 1, - start + nn, - &dummy, - &ah ); + ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface, + 1, + start + nn, + &dummy, + &ah ); FT_TRACE5(( " idx %d: advance height %d font unit%s\n", start + nn, @@ -259,12 +259,12 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* no fast retrieval for blended MM fonts without HVAR table */ if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && - !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + !( cffface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) return FT_THROW( Unimplemented_Feature ); #endif /* check whether we have data from the `hmtx' table at all */ - if ( !ttface->horizontal.number_Of_HMetrics ) + if ( !cffface->horizontal.number_Of_HMetrics ) goto Missing_Table; for ( nn = 0; nn < count; nn++ ) @@ -272,11 +272,11 @@ FT_UShort aw; - ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface, - 0, - start + nn, - &dummy, - &aw ); + ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface, + 0, + start + nn, + &dummy, + &aw ); FT_TRACE5(( " idx %d: advance width %d font unit%s\n", start + nn, @@ -312,13 +312,14 @@ * */ - static FT_Error - cff_get_glyph_name( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_get_glyph_name( FT_Face face, /* CFF_Face */ FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) { - CFF_Font font = (CFF_Font)face->extra.data; + CFF_Face cffface = (CFF_Face)face; + CFF_Font font = (CFF_Font)cffface->extra.data; FT_String* gname; FT_UShort sid; FT_Error error; @@ -338,10 +339,7 @@ if ( service && service->get_name ) - return service->get_name( FT_FACE( face ), - glyph_index, - buffer, - buffer_max ); + return service->get_name( face, glyph_index, buffer, buffer_max ); else { FT_ERROR(( "cff_get_glyph_name:" @@ -366,7 +364,7 @@ /* first, locate the sid in the charset table */ sid = font->charset.sids[glyph_index]; - /* now, lookup the name itself */ + /* now, look up the name itself */ gname = cff_index_get_sid_string( font, sid ); if ( gname ) @@ -379,21 +377,19 @@ } - static FT_UInt - cff_get_name_index( CFF_Face face, + FT_CALLBACK_DEF( FT_UInt ) + cff_get_name_index( FT_Face face, /* CFF_Face */ const FT_String* glyph_name ) { - CFF_Font cff; - CFF_Charset charset; + CFF_Face cffface = (CFF_Face)face; + CFF_Font cff = (CFF_Font)cffface->extra.data; + CFF_Charset charset = &cff->charset; FT_Service_PsCMaps psnames; FT_String* name; FT_UShort sid; FT_UInt i; - cff = (CFF_FontRec *)face->extra.data; - charset = &cff->charset; - /* CFF2 table does not have glyph names; */ /* we need to use `post' table method */ if ( cff->version_major == 2 ) @@ -408,7 +404,7 @@ if ( service && service->name_index ) - return service->name_index( FT_FACE( face ), glyph_name ); + return service->name_index( face, glyph_name ); else { FT_ERROR(( "cff_get_name_index:" @@ -446,8 +442,8 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( cff_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, /* get_name */ - (FT_GlyphDict_NameIndexFunc)cff_get_name_index /* name_index */ + cff_get_glyph_name, /* FT_GlyphDict_GetNameFunc get_name */ + cff_get_name_index /* FT_GlyphDict_NameIndexFunc name_index */ ) @@ -456,25 +452,32 @@ * */ - static FT_Int + FT_CALLBACK_DEF( FT_Int ) cff_ps_has_glyph_names( FT_Face face ) { return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; } - static FT_Error - cff_ps_get_font_info( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_ps_get_font_info( FT_Face face, /* CFF_Face */ PS_FontInfoRec* afont_info ) { - CFF_Font cff = (CFF_Font)face->extra.data; - FT_Error error = FT_Err_Ok; + CFF_Face cffface = (CFF_Face)face; + CFF_Font cff = (CFF_Font)cffface->extra.data; + FT_Error error = FT_Err_Ok; + if ( cffface->is_cff2 ) + { + error = FT_THROW( Invalid_Argument ); + goto Fail; + } + if ( cff && !cff->font_info ) { CFF_FontRecDict dict = &cff->top_font.font_dict; - FT_Memory memory = face->root.memory; + FT_Memory memory = FT_FACE_MEMORY( face ); PS_FontInfoRec* font_info = NULL; @@ -507,18 +510,19 @@ } - static FT_Error - cff_ps_get_font_extra( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_ps_get_font_extra( FT_Face face, /* CFF_Face */ PS_FontExtraRec* afont_extra ) { - CFF_Font cff = (CFF_Font)face->extra.data; - FT_Error error = FT_Err_Ok; + CFF_Face cffface = (CFF_Face)face; + CFF_Font cff = (CFF_Font)cffface->extra.data; + FT_Error error = FT_Err_Ok; if ( cff && !cff->font_extra ) { CFF_FontRecDict dict = &cff->top_font.font_dict; - FT_Memory memory = face->root.memory; + FT_Memory memory = FT_FACE_MEMORY( face ); PS_FontExtraRec* font_extra = NULL; FT_String* embedded_postscript; @@ -588,13 +592,13 @@ FT_DEFINE_SERVICE_PSINFOREC( cff_service_ps_info, - (PS_GetFontInfoFunc) cff_ps_get_font_info, /* ps_get_font_info */ - (PS_GetFontExtraFunc) cff_ps_get_font_extra, /* ps_get_font_extra */ - (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, /* ps_has_glyph_names */ + cff_ps_get_font_info, /* PS_GetFontInfoFunc ps_get_font_info */ + cff_ps_get_font_extra, /* PS_GetFontExtraFunc ps_get_font_extra */ + cff_ps_has_glyph_names, /* PS_HasGlyphNamesFunc ps_has_glyph_names */ /* unsupported with CFF fonts */ - (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + NULL, /* PS_GetFontPrivateFunc ps_get_font_private */ /* not implemented */ - (PS_GetFontValueFunc) NULL /* ps_get_font_value */ + NULL /* PS_GetFontValueFunc ps_get_font_value */ ) @@ -603,17 +607,18 @@ * */ - static const char* - cff_get_ps_name( CFF_Face face ) + FT_CALLBACK_DEF( const char* ) + cff_get_ps_name( FT_Face face ) /* CFF_Face */ { - CFF_Font cff = (CFF_Font)face->extra.data; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + CFF_Face cffface = (CFF_Face)face; + CFF_Font cff = (CFF_Font)cffface->extra.data; + SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; /* following the OpenType specification 1.7, we return the name stored */ /* in the `name' table for a CFF wrapped into an SFNT container */ - if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt ) + if ( FT_IS_SFNT( face ) && sfnt ) { FT_Library library = FT_FACE_LIBRARY( face ); FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); @@ -625,17 +630,17 @@ if ( service && service->get_ps_font_name ) - return service->get_ps_font_name( FT_FACE( face ) ); + return service->get_ps_font_name( face ); } - return (const char*)cff->font_name; + return cff ? (const char*)cff->font_name : NULL; } FT_DEFINE_SERVICE_PSFONTNAMEREC( cff_service_ps_name, - (FT_PsName_GetFunc)cff_get_ps_name /* get_ps_font_name */ + cff_get_ps_name /* FT_PsName_GetFunc get_ps_font_name */ ) @@ -649,7 +654,7 @@ * Otherwise call the service function in the sfnt module. * */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) cff_get_cmap_info( FT_CharMap charmap, TT_CMapInfo *cmap_info ) { @@ -683,7 +688,7 @@ FT_DEFINE_SERVICE_TTCMAPSREC( cff_service_get_cmap_info, - (TT_CMap_Info_GetFunc)cff_get_cmap_info /* get_cmap_info */ + cff_get_cmap_info /* TT_CMap_Info_GetFunc get_cmap_info */ ) @@ -691,14 +696,15 @@ * CID INFO SERVICE * */ - static FT_Error - cff_get_ros( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_get_ros( FT_Face face, /* FT_Face */ const char* *registry, const char* *ordering, FT_Int *supplement ) { - FT_Error error = FT_Err_Ok; - CFF_Font cff = (CFF_Font)face->extra.data; + FT_Error error = FT_Err_Ok; + CFF_Face cffface = (CFF_Face)face; + CFF_Font cff = (CFF_Font)cffface->extra.data; if ( cff ) @@ -748,12 +754,13 @@ } - static FT_Error - cff_get_is_cid( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_get_is_cid( FT_Face face, /* CFF_Face */ FT_Bool *is_cid ) { - FT_Error error = FT_Err_Ok; - CFF_Font cff = (CFF_Font)face->extra.data; + FT_Error error = FT_Err_Ok; + CFF_Face cffface = (CFF_Face)face; + CFF_Font cff = (CFF_Font)cffface->extra.data; *is_cid = 0; @@ -771,16 +778,15 @@ } - static FT_Error - cff_get_cid_from_glyph_index( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_get_cid_from_glyph_index( FT_Face face, /* CFF_Face */ FT_UInt glyph_index, FT_UInt *cid ) { - FT_Error error = FT_Err_Ok; - CFF_Font cff; - + FT_Error error = FT_Err_Ok; + CFF_Face cffface = (CFF_Face)face; + CFF_Font cff = (CFF_Font)cffface->extra.data; - cff = (CFF_Font)face->extra.data; if ( cff ) { @@ -814,12 +820,12 @@ FT_DEFINE_SERVICE_CIDREC( cff_service_cid_info, - (FT_CID_GetRegistryOrderingSupplementFunc) - cff_get_ros, /* get_ros */ - (FT_CID_GetIsInternallyCIDKeyedFunc) - cff_get_is_cid, /* get_is_cid */ - (FT_CID_GetCIDFromGlyphIndexFunc) - cff_get_cid_from_glyph_index /* get_cid_from_glyph_index */ + cff_get_ros, + /* FT_CID_GetRegistryOrderingSupplementFunc get_ros */ + cff_get_is_cid, + /* FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid */ + cff_get_cid_from_glyph_index + /* FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index */ ) @@ -831,9 +837,9 @@ FT_DEFINE_SERVICE_PROPERTIESREC( cff_service_properties, - (FT_Properties_SetFunc)ps_property_set, /* set_property */ - (FT_Properties_GetFunc)ps_property_get ) /* get_property */ - + ps_property_set, /* FT_Properties_SetFunc set_property */ + ps_property_get /* FT_Properties_GetFunc get_property */ + ) #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -842,160 +848,195 @@ * */ - static FT_Error - cff_set_mm_blend( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_set_mm_blend( FT_Face face, /* CFF_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->set_mm_blend( FT_FACE( face ), num_coords, coords ); + return mm->set_mm_blend( face, num_coords, coords ); } - static FT_Error - cff_get_mm_blend( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_get_mm_blend( FT_Face face, /* CFF_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->get_mm_blend( FT_FACE( face ), num_coords, coords ); + return mm->get_mm_blend( face, num_coords, coords ); } - static FT_Error - cff_set_mm_weightvector( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_set_mm_weightvector( FT_Face face, /* CFF_Face */ FT_UInt len, FT_Fixed* weightvector ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->set_mm_weightvector( FT_FACE( face ), len, weightvector ); + return mm->set_mm_weightvector( face, len, weightvector ); } - static FT_Error - cff_get_mm_weightvector( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_get_mm_weightvector( FT_Face face, /* CFF_Face */ FT_UInt* len, FT_Fixed* weightvector ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->get_mm_weightvector( FT_FACE( face ), len, weightvector ); + return mm->get_mm_weightvector( face, len, weightvector ); } - static FT_Error - cff_get_mm_var( CFF_Face face, + FT_CALLBACK_DEF( void ) + cff_construct_ps_name( FT_Face face ) /* CFF_Face */ + { + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; + + + mm->construct_ps_name( face ); + } + + + FT_CALLBACK_DEF( FT_Error ) + cff_get_mm_var( FT_Face face, /* CFF_Face */ FT_MM_Var* *master ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->get_mm_var( FT_FACE( face ), master ); + return mm->get_mm_var( face, master ); } - static FT_Error - cff_set_var_design( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_set_var_design( FT_Face face, /* CFF_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->set_var_design( FT_FACE( face ), num_coords, coords ); + return mm->set_var_design( face, num_coords, coords ); } - static FT_Error - cff_get_var_design( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_get_var_design( FT_Face face, /* CFF_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->get_var_design( FT_FACE( face ), num_coords, coords ); + return mm->get_var_design( face, num_coords, coords ); } - static FT_Error - cff_set_instance( CFF_Face face, - FT_UInt instance_index ) + FT_CALLBACK_DEF( FT_Error ) + cff_set_named_instance( FT_Face face, /* CFF_Face */ + FT_UInt instance_index ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->set_instance( FT_FACE( face ), instance_index ); + return mm->set_named_instance( face, instance_index ); } - static FT_Error - cff_load_item_variation_store( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_get_default_named_instance( FT_Face face, /* CFF_Face */ + FT_UInt *instance_index ) + { + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; + + + return mm->get_default_named_instance( face, instance_index ); + } + + + FT_CALLBACK_DEF( FT_Error ) + cff_load_item_variation_store( FT_Face face, /* CFF_Face */ FT_ULong offset, GX_ItemVarStore itemStore ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->load_item_var_store( FT_FACE(face), offset, itemStore ); + return mm->load_item_var_store( face, offset, itemStore ); } - static FT_Error - cff_load_delta_set_index_mapping( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_load_delta_set_index_mapping( FT_Face face, /* CFF_Face */ FT_ULong offset, GX_DeltaSetIdxMap map, GX_ItemVarStore itemStore, FT_ULong table_len ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->load_delta_set_idx_map( FT_FACE( face ), offset, map, + return mm->load_delta_set_idx_map( face, offset, map, itemStore, table_len ); } - static FT_Int - cff_get_item_delta( CFF_Face face, + FT_CALLBACK_DEF( FT_Int ) + cff_get_item_delta( FT_Face face, /* CFF_Face */ GX_ItemVarStore itemStore, FT_UInt outerIndex, FT_UInt innerIndex ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->get_item_delta( FT_FACE( face ), itemStore, - outerIndex, innerIndex ); + return mm->get_item_delta( face, itemStore, outerIndex, innerIndex ); } - static void - cff_done_item_variation_store( CFF_Face face, + FT_CALLBACK_DEF( void ) + cff_done_item_variation_store( FT_Face face, /* CFF_Face */ GX_ItemVarStore itemStore ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - mm->done_item_var_store( FT_FACE( face ), itemStore ); + mm->done_item_var_store( face, itemStore ); } - static void - cff_done_delta_set_index_map( CFF_Face face, + FT_CALLBACK_DEF( void ) + cff_done_delta_set_index_map( FT_Face face, /* CFF_Face */ GX_DeltaSetIdxMap deltaSetIdxMap ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - mm->done_delta_set_idx_map( FT_FACE ( face ), deltaSetIdxMap ); + mm->done_delta_set_idx_map( face, deltaSetIdxMap ); } @@ -1003,36 +1044,35 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( cff_service_multi_masters, - (FT_Get_MM_Func) NULL, /* get_mm */ - (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ - (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */ - (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */ - (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */ - (FT_Set_Instance_Func) cff_set_instance, /* set_instance */ - (FT_Set_MM_WeightVector_Func) - cff_set_mm_weightvector, - /* set_mm_weightvector */ - (FT_Get_MM_WeightVector_Func) - cff_get_mm_weightvector, - /* get_mm_weightvector */ - (FT_Var_Load_Delta_Set_Idx_Map_Func) - cff_load_delta_set_index_mapping, - /* load_delta_set_idx_map */ - (FT_Var_Load_Item_Var_Store_Func) - cff_load_item_variation_store, - /* load_item_variation_store */ - (FT_Var_Get_Item_Delta_Func) - cff_get_item_delta, /* get_item_delta */ - (FT_Var_Done_Item_Var_Store_Func) - cff_done_item_variation_store, - /* done_item_variation_store */ - (FT_Var_Done_Delta_Set_Idx_Map_Func) - cff_done_delta_set_index_map, - /* done_delta_set_index_map */ - (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ - (FT_Done_Blend_Func) cff_done_blend /* done_blend */ + NULL, /* FT_Get_MM_Func get_mm */ + NULL, /* FT_Set_MM_Design_Func set_mm_design */ + cff_set_mm_blend, /* FT_Set_MM_Blend_Func set_mm_blend */ + cff_get_mm_blend, /* FT_Get_MM_Blend_Func get_mm_blend */ + cff_get_mm_var, /* FT_Get_MM_Var_Func get_mm_var */ + cff_set_var_design, /* FT_Set_Var_Design_Func set_var_design */ + cff_get_var_design, /* FT_Get_Var_Design_Func get_var_design */ + cff_set_named_instance, + /* FT_Set_Named_Instance_Func set_named_instance */ + cff_get_default_named_instance, + /* FT_Get_Default_Named_Instance_Func get_default_named_instance */ + cff_set_mm_weightvector, + /* FT_Set_MM_WeightVector_Func set_mm_weightvector */ + cff_get_mm_weightvector, + /* FT_Get_MM_WeightVector_Func get_mm_weightvector */ + cff_construct_ps_name, + /* FT_Construct_PS_Name_Func construct_ps_name */ + cff_load_delta_set_index_mapping, + /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map */ + cff_load_item_variation_store, + /* FT_Var_Load_Item_Var_Store_Func load_item_variation_store */ + cff_get_item_delta, + /* FT_Var_Get_Item_Delta_Func get_item_delta */ + cff_done_item_variation_store, + /* FT_Var_Done_Item_Var_Store_Func done_item_variation_store */ + cff_done_delta_set_index_map, + /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map */ + cff_get_var_blend, /* FT_Get_Var_Blend_Func get_var_blend */ + cff_done_blend /* FT_Done_Blend_Func done_blend */ ) @@ -1041,41 +1081,46 @@ * */ - static FT_Error - cff_hadvance_adjust( CFF_Face face, + FT_CALLBACK_DEF( FT_Error ) + cff_hadvance_adjust( FT_Face face, /* CFF_Face */ FT_UInt gindex, FT_Int *avalue ) { - FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MetricsVariations + var = (FT_Service_MetricsVariations)cffface->tt_var; - return var->hadvance_adjust( FT_FACE( face ), gindex, avalue ); + return var->hadvance_adjust( face, gindex, avalue ); } - static void - cff_metrics_adjust( CFF_Face face ) + FT_CALLBACK_DEF( void ) + cff_metrics_adjust( FT_Face face ) /* CFF_Face */ { - FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MetricsVariations + var = (FT_Service_MetricsVariations)cffface->tt_var; - var->metrics_adjust( FT_FACE( face ) ); + var->metrics_adjust( face ); } FT_DEFINE_SERVICE_METRICSVARIATIONSREC( cff_service_metrics_variations, - (FT_HAdvance_Adjust_Func)cff_hadvance_adjust, /* hadvance_adjust */ - (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */ - (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */ + cff_hadvance_adjust, /* FT_HAdvance_Adjust_Func hadvance_adjust */ + NULL, /* FT_LSB_Adjust_Func lsb_adjust */ + NULL, /* FT_RSB_Adjust_Func rsb_adjust */ - (FT_VAdvance_Adjust_Func)NULL, /* vadvance_adjust */ - (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */ - (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ - (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ + NULL, /* FT_VAdvance_Adjust_Func vadvance_adjust */ + NULL, /* FT_TSB_Adjust_Func tsb_adjust */ + NULL, /* FT_BSB_Adjust_Func bsb_adjust */ + NULL, /* FT_VOrg_Adjust_Func vorg_adjust */ - (FT_Metrics_Adjust_Func) cff_metrics_adjust /* metrics_adjust */ + cff_metrics_adjust, /* FT_Metrics_Adjust_Func metrics_adjust */ + NULL /* FT_Size_Reset_Func size_reset */ ) #endif @@ -1088,11 +1133,11 @@ FT_DEFINE_SERVICE_CFFLOADREC( cff_service_cff_load, - (FT_Get_Standard_Encoding_Func)cff_get_standard_encoding, - (FT_Load_Private_Dict_Func) cff_load_private_dict, - (FT_FD_Select_Get_Func) cff_fd_select_get, - (FT_Blend_Check_Vector_Func) cff_blend_check_vector, - (FT_Blend_Build_Vector_Func) cff_blend_build_vector + cff_get_standard_encoding, /* FT_Get_Standard_Encoding_Func get_standard_encoding */ + cff_load_private_dict, /* FT_Load_Private_Dict_Func load_private_dict */ + cff_fd_select_get, /* FT_FD_Select_Get_Func fd_select_get */ + cff_blend_check_vector, /* FT_Blend_Check_Vector_Func blend_check_vector */ + cff_blend_build_vector /* FT_Blend_Build_Vector_Func blend_build_vector */ ) diff --git a/thirdparty/freetype/src/cff/cffgload.c b/thirdparty/freetype/src/cff/cffgload.c index cfa0aaf2b6..c483d1d1a5 100644 --- a/thirdparty/freetype/src/cff/cffgload.c +++ b/thirdparty/freetype/src/cff/cffgload.c @@ -356,14 +356,16 @@ #ifdef FT_CONFIG_OPTION_SVG /* check for OT-SVG */ - if ( ( load_flags & FT_LOAD_COLOR ) && face->svg ) + if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 && + ( load_flags & FT_LOAD_COLOR ) && + face->svg ) { /* * We load the SVG document and try to grab the advances from the * table. For the bearings we rely on the presetting hook to do that. */ - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; if ( size && (size->root.metrics.x_ppem < 1 || diff --git a/thirdparty/freetype/src/cff/cffload.c b/thirdparty/freetype/src/cff/cffload.c index 4b8c6e16c5..f96002ec0b 100644 --- a/thirdparty/freetype/src/cff/cffload.c +++ b/thirdparty/freetype/src/cff/cffload.c @@ -400,7 +400,7 @@ /* Allocate a table containing pointers to an index's elements. */ /* The `pool' argument makes this function convert the index */ - /* entries to C-style strings (this is, null-terminated). */ + /* entries to C-style strings (that is, null-terminated). */ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, @@ -1589,16 +1589,17 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_LOCAL_DEF( FT_Error ) - cff_get_var_blend( CFF_Face face, + cff_get_var_blend( FT_Face face, /* CFF_Face */ FT_UInt *num_coords, FT_Fixed* *coords, FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ) { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - return mm->get_var_blend( FT_FACE( face ), + return mm->get_var_blend( face, num_coords, coords, normalizedcoords, @@ -1607,13 +1608,14 @@ FT_LOCAL_DEF( void ) - cff_done_blend( CFF_Face face ) + cff_done_blend( FT_Face face ) /* CFF_Face */ { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + CFF_Face cffface = (CFF_Face)face; + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; - if (mm) - mm->done_blend( FT_FACE( face ) ); + if ( mm ) + mm->done_blend( face ); } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1650,13 +1652,6 @@ goto Exit; } - /* Zero out the code to gid/sid mappings. */ - for ( j = 0; j < 256; j++ ) - { - encoding->sids [j] = 0; - encoding->codes[j] = 0; - } - /* Note: The encoding table in a CFF font is indexed by glyph index; */ /* the first encoded glyph index is 1. Hence, we read the character */ /* code (`glyph_code') at index j and make the assignment: */ @@ -1671,6 +1666,10 @@ if ( offset > 1 ) { + /* Zero out the code to gid/sid mappings. */ + FT_ARRAY_ZERO( encoding->sids, 256 ); + FT_ARRAY_ZERO( encoding->codes, 256 ); + encoding->offset = base_offset + offset; /* we need to parse the table to determine its size */ @@ -2012,7 +2011,7 @@ /* Top and Font DICTs are not allowed to have blend operators. */ error = cff_parser_init( &parser, code, - &subfont->font_dict, + top, font->library, stackSize, 0, diff --git a/thirdparty/freetype/src/cff/cffload.h b/thirdparty/freetype/src/cff/cffload.h index 5a41cdebc8..b5286b0c8c 100644 --- a/thirdparty/freetype/src/cff/cffload.h +++ b/thirdparty/freetype/src/cff/cffload.h @@ -105,14 +105,14 @@ FT_BEGIN_HEADER #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_LOCAL( FT_Error ) - cff_get_var_blend( CFF_Face face, + cff_get_var_blend( FT_Face face, FT_UInt *num_coords, FT_Fixed* *coords, FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ); FT_LOCAL( void ) - cff_done_blend( CFF_Face face ); + cff_done_blend( FT_Face face ); #endif diff --git a/thirdparty/freetype/src/cff/cffobjs.c b/thirdparty/freetype/src/cff/cffobjs.c index 40cd9bf917..6d08620c48 100644 --- a/thirdparty/freetype/src/cff/cffobjs.c +++ b/thirdparty/freetype/src/cff/cffobjs.c @@ -69,8 +69,8 @@ FT_Module module; - module = FT_Get_Module( size->root.face->driver->root.library, - "pshinter" ); + module = FT_Get_Module( font->library, "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) : 0; @@ -182,8 +182,7 @@ goto Exit; cff_make_private_dict( &font->top_font, &priv ); - error = funcs->create( cffsize->face->memory, &priv, - &internal->topfont ); + error = funcs->create( memory, &priv, &internal->topfont ); if ( error ) goto Exit; @@ -193,8 +192,7 @@ cff_make_private_dict( sub, &priv ); - error = funcs->create( cffsize->face->memory, &priv, - &internal->subfonts[i - 1] ); + error = funcs->create( memory, &priv, &internal->subfonts[i - 1] ); if ( error ) goto Exit; } @@ -381,8 +379,7 @@ FT_Module module; - module = FT_Get_Module( slot->face->driver->root.library, - "pshinter" ); + module = FT_Get_Module( slot->library, "pshinter" ); if ( module ) { T2_Hints_Funcs funcs; @@ -722,22 +719,15 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; - FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var; - FT_UInt instance_index = (FT_UInt)face_index >> 16; if ( FT_HAS_MULTIPLE_MASTERS( cffface ) && - mm && instance_index > 0 ) { - error = mm->set_instance( cffface, instance_index ); + error = FT_Set_Named_Instance( cffface, instance_index ); if ( error ) goto Exit; - - if ( var ) - var->metrics_adjust( cffface ); } } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1160,7 +1150,7 @@ } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - cff_done_blend( face ); + cff_done_blend( cffface ); face->blend = NULL; #endif } diff --git a/thirdparty/freetype/src/cff/cffparse.c b/thirdparty/freetype/src/cff/cffparse.c index e16206fd55..c850dfc61e 100644 --- a/thirdparty/freetype/src/cff/cffparse.c +++ b/thirdparty/freetype/src/cff/cffparse.c @@ -63,10 +63,7 @@ /* allocate the stack buffer */ if ( FT_QNEW_ARRAY( parser->stack, stackSize ) ) - { - FT_FREE( parser->stack ); goto Exit; - } parser->stackSize = stackSize; parser->top = parser->stack; /* empty stack */ @@ -76,23 +73,6 @@ } -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - static void - finalize_t2_strings( FT_Memory memory, - void* data, - void* user ) - { - CFF_T2_String t2 = (CFF_T2_String)data; - - - FT_UNUSED( user ); - - memory->free( memory, t2->start ); - memory->free( memory, data ); - } -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - - FT_LOCAL_DEF( void ) cff_parser_done( CFF_Parser parser ) { @@ -102,63 +82,19 @@ FT_FREE( parser->stack ); #ifdef CFF_CONFIG_OPTION_OLD_ENGINE - FT_List_Finalize( &parser->t2_strings, - finalize_t2_strings, - memory, - NULL ); + FT_List_Finalize( &parser->t2_strings, NULL, memory, NULL ); #endif } - /* Assuming `first >= last'. */ - - static FT_Error - cff_parser_within_limits( CFF_Parser parser, - FT_Byte* first, - FT_Byte* last ) - { -#ifndef CFF_CONFIG_OPTION_OLD_ENGINE - - /* Fast path for regular FreeType builds with the "new" engine; */ - /* `first >= parser->start' can be assumed. */ - - FT_UNUSED( first ); - - return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument ); - -#else /* CFF_CONFIG_OPTION_OLD_ENGINE */ - - FT_ListNode node; - - - if ( first >= parser->start && - last < parser->limit ) - return FT_Err_Ok; - - node = parser->t2_strings.head; - - while ( node ) - { - CFF_T2_String t2 = (CFF_T2_String)node->data; - - - if ( first >= t2->start && - last < t2->limit ) - return FT_Err_Ok; - - node = node->next; - } - - return FT_THROW( Invalid_Argument ); - -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - } - + /* The parser limit checks in the next two functions are supposed */ + /* to detect the immediate crossing of the stream boundary. They */ + /* shall not be triggered from the distant t2_strings buffers. */ /* read an integer */ static FT_Long - cff_parse_integer( CFF_Parser parser, - FT_Byte* start ) + cff_parse_integer( FT_Byte* start, + FT_Byte* limit ) { FT_Byte* p = start; FT_Int v = *p++; @@ -167,14 +103,14 @@ if ( v == 28 ) { - if ( cff_parser_within_limits( parser, p, p + 1 ) ) + if ( p + 2 > limit && limit >= p ) goto Bad; val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] ); } else if ( v == 29 ) { - if ( cff_parser_within_limits( parser, p, p + 3 ) ) + if ( p + 4 > limit && limit >= p ) goto Bad; val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) | @@ -188,14 +124,14 @@ } else if ( v < 251 ) { - if ( cff_parser_within_limits( parser, p, p ) ) + if ( p + 1 > limit && limit >= p ) goto Bad; val = ( v - 247 ) * 256 + p[0] + 108; } else { - if ( cff_parser_within_limits( parser, p, p ) ) + if ( p + 1 > limit && limit >= p ) goto Bad; val = -( v - 251 ) * 256 - p[0] - 108; @@ -244,10 +180,10 @@ /* read a real */ static FT_Fixed - cff_parse_real( CFF_Parser parser, - FT_Byte* start, - FT_Long power_ten, - FT_Long* scaling ) + cff_parse_real( FT_Byte* start, + FT_Byte* limit, + FT_Long power_ten, + FT_Long* scaling ) { FT_Byte* p = start; FT_Int nib; @@ -282,7 +218,7 @@ p++; /* Make sure we don't read past the end. */ - if ( cff_parser_within_limits( parser, p, p ) ) + if ( p + 1 > limit && limit >= p ) goto Bad; } @@ -319,7 +255,7 @@ p++; /* Make sure we don't read past the end. */ - if ( cff_parser_within_limits( parser, p, p ) ) + if ( p + 1 > limit && limit >= p ) goto Bad; } @@ -358,7 +294,7 @@ p++; /* Make sure we don't read past the end. */ - if ( cff_parser_within_limits( parser, p, p ) ) + if ( p + 1 > limit && limit >= p ) goto Bad; } @@ -525,7 +461,7 @@ if ( **d == 30 ) { /* binary-coded decimal is truncated to integer */ - return cff_parse_real( parser, *d, 0, NULL ) >> 16; + return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16; } else if ( **d == 255 ) @@ -551,7 +487,7 @@ } else - return cff_parse_integer( parser, *d ); + return cff_parse_integer( *d, parser->limit ); } @@ -562,10 +498,10 @@ FT_Long scaling ) { if ( **d == 30 ) - return cff_parse_real( parser, *d, scaling, NULL ); + return cff_parse_real( *d, parser->limit, scaling, NULL ); else { - FT_Long val = cff_parse_integer( parser, *d ); + FT_Long val = cff_parse_integer( *d, parser->limit ); if ( scaling ) @@ -630,14 +566,14 @@ FT_ASSERT( scaling ); if ( **d == 30 ) - return cff_parse_real( parser, *d, 0, scaling ); + return cff_parse_real( *d, parser->limit, 0, scaling ); else { FT_Long number; FT_Int integer_length; - number = cff_parse_integer( parser, d[0] ); + number = cff_parse_integer( *d, parser->limit ); if ( number > 0x7FFFL ) { @@ -686,7 +622,7 @@ dict->has_font_matrix = TRUE; - /* We expect a well-formed font matrix, this is, the matrix elements */ + /* We expect a well-formed font matrix, that is, the matrix elements */ /* `xx' and `yy' are of approximately the same magnitude. To avoid */ /* loss of precision, we use the magnitude of the largest matrix */ /* element to scale all other elements. The scaling factor is then */ @@ -1264,11 +1200,8 @@ FT_Byte* charstring_base; FT_ULong charstring_len; - FT_Fixed* stack; - FT_ListNode node; - CFF_T2_String t2; - FT_Fixed t2_size; - FT_Byte* q; + FT_Fixed* stack; + FT_Byte* q = NULL; charstring_base = ++p; @@ -1309,39 +1242,18 @@ /* Now copy the stack data in the temporary decoder object, */ /* converting it back to charstring number representations */ /* (this is ugly, I know). */ + /* The maximum required size is 5 bytes per stack element. */ + if ( FT_QALLOC( q, (FT_Long)( 2 * sizeof ( FT_ListNode ) ) + + 5 * ( decoder.top - decoder.stack ) ) ) + goto Exit; - node = (FT_ListNode)memory->alloc( memory, - sizeof ( FT_ListNodeRec ) ); - if ( !node ) - goto Out_Of_Memory_Error; - - FT_List_Add( &parser->t2_strings, node ); - - t2 = (CFF_T2_String)memory->alloc( memory, - sizeof ( CFF_T2_StringRec ) ); - if ( !t2 ) - goto Out_Of_Memory_Error; - - node->data = t2; - - /* `5' is the conservative upper bound of required bytes per stack */ - /* element. */ - - t2_size = 5 * ( decoder.top - decoder.stack ); - - q = (FT_Byte*)memory->alloc( memory, t2_size ); - if ( !q ) - goto Out_Of_Memory_Error; - - t2->start = q; - t2->limit = q + t2_size; + FT_List_Add( &parser->t2_strings, (FT_ListNode)q ); - stack = decoder.stack; + q += 2 * sizeof ( FT_ListNode ); - while ( stack < decoder.top ) + for ( stack = decoder.stack; stack < decoder.top; stack++ ) { - FT_ULong num; - FT_Bool neg; + FT_Long num = *stack; if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) @@ -1349,69 +1261,37 @@ *parser->top++ = q; - if ( *stack < 0 ) - { - num = (FT_ULong)NEG_LONG( *stack ); - neg = 1; - } - else - { - num = (FT_ULong)*stack; - neg = 0; - } - if ( num & 0xFFFFU ) { - if ( neg ) - num = (FT_ULong)-num; - *q++ = 255; - *q++ = ( num & 0xFF000000U ) >> 24; - *q++ = ( num & 0x00FF0000U ) >> 16; - *q++ = ( num & 0x0000FF00U ) >> 8; - *q++ = num & 0x000000FFU; + *q++ = (FT_Byte)( ( num >> 24 ) & 0xFF ); + *q++ = (FT_Byte)( ( num >> 16 ) & 0xFF ); + *q++ = (FT_Byte)( ( num >> 8 ) & 0xFF ); + *q++ = (FT_Byte)( ( num ) & 0xFF ); } else { num >>= 16; - if ( neg ) + if ( -107 <= num && num <= 107 ) + *q++ = (FT_Byte)( num + 139 ); + else if ( 108 <= num && num <= 1131 ) { - if ( num <= 107 ) - *q++ = (FT_Byte)( 139 - num ); - else if ( num <= 1131 ) - { - *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 ); - *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); - } - else - { - num = (FT_ULong)-num; - - *q++ = 28; - *q++ = (FT_Byte)( num >> 8 ); - *q++ = (FT_Byte)( num & 0xFF ); - } + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else if ( -1131 <= num && num <= -108 ) + { + *q++ = (FT_Byte)( ( ( -num - 108 ) >> 8 ) + 251 ); + *q++ = (FT_Byte)( ( -num - 108) & 0xFF ); } else { - if ( num <= 107 ) - *q++ = (FT_Byte)( num + 139 ); - else if ( num <= 1131 ) - { - *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 ); - *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); - } - else - { - *q++ = 28; - *q++ = (FT_Byte)( num >> 8 ); - *q++ = (FT_Byte)( num & 0xFF ); - } + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); } } - - stack++; } } #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ @@ -1598,12 +1478,6 @@ Exit: return error; -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - Out_Of_Memory_Error: - error = FT_THROW( Out_Of_Memory ); - goto Exit; -#endif - Stack_Overflow: error = FT_THROW( Invalid_Argument ); goto Exit; diff --git a/thirdparty/freetype/src/cff/cffparse.h b/thirdparty/freetype/src/cff/cffparse.h index 58d59fa4ac..b6378a8e8d 100644 --- a/thirdparty/freetype/src/cff/cffparse.h +++ b/thirdparty/freetype/src/cff/cffparse.h @@ -133,15 +133,6 @@ FT_BEGIN_HEADER FT_END_HEADER -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - typedef struct CFF_T2_String_ - { - FT_Byte* start; - FT_Byte* limit; - - } CFF_T2_StringRec, *CFF_T2_String; -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - #endif /* CFFPARSE_H_ */ diff --git a/thirdparty/freetype/src/cid/cidgload.c b/thirdparty/freetype/src/cid/cidgload.c index ba4b7565d5..eaca765ad0 100644 --- a/thirdparty/freetype/src/cid/cidgload.c +++ b/thirdparty/freetype/src/cid/cidgload.c @@ -40,6 +40,117 @@ #define FT_COMPONENT cidgload + /* + * A helper function to compute FD number (`fd_select`), the offset to the + * head of the glyph data (`off1`), and the offset to the and of the glyph + * data (`off2`). + * + * The number how many times `cid_get_offset` is invoked can be controlled + * by the number of non-NULL arguments. If `fd_select` is non-NULL but + * `off1` and `off2` are NULL, `cid_get_offset` is invoked only for + * `fd_select`; `off1` and `off2` are not validated. + * + */ + FT_LOCAL_DEF( FT_Error ) + cid_compute_fd_and_offsets( CID_Face face, + FT_UInt glyph_index, + FT_ULong* fd_select_p, + FT_ULong* off1_p, + FT_ULong* off2_p ) + { + FT_Error error = FT_Err_Ok; + + CID_FaceInfo cid = &face->cid; + FT_Stream stream = face->cid_stream; + FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; + + FT_Byte* p; + FT_Bool need_frame_exit = 0; + FT_ULong fd_select, off1, off2; + + + /* For ordinary fonts, read the CID font dictionary index */ + /* and charstring offset from the CIDMap. */ + + if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + + glyph_index * entry_len ) || + FT_FRAME_ENTER( 2 * entry_len ) ) + goto Exit; + + need_frame_exit = 1; + + p = (FT_Byte*)stream->cursor; + fd_select = cid_get_offset( &p, cid->fd_bytes ); + off1 = cid_get_offset( &p, cid->gd_bytes ); + + p += cid->fd_bytes; + off2 = cid_get_offset( &p, cid->gd_bytes ); + + if ( fd_select_p ) + *fd_select_p = fd_select; + if ( off1_p ) + *off1_p = off1; + if ( off2_p ) + *off2_p = off2; + + if ( fd_select >= cid->num_dicts ) + { + /* + * fd_select == 0xFF is often used to indicate that the CID + * has no charstring to be rendered, similar to GID = 0xFFFF + * in TrueType fonts. + */ + if ( ( cid->fd_bytes == 1 && fd_select == 0xFFU ) || + ( cid->fd_bytes == 2 && fd_select == 0xFFFFU ) ) + { + FT_TRACE1(( "cid_load_glyph: fail for glyph index %d:\n", + glyph_index )); + FT_TRACE1(( " FD number %ld is the maximum\n", + fd_select )); + FT_TRACE1(( " integer fitting into %d byte%s\n", + cid->fd_bytes, cid->fd_bytes == 1 ? "" : "s" )); + } + else + { + FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n", + glyph_index )); + FT_TRACE0(( " FD number %ld is larger\n", + fd_select )); + FT_TRACE0(( " than number of dictionaries (%d)\n", + cid->num_dicts )); + } + + error = FT_THROW( Invalid_Offset ); + goto Exit; + } + else if ( off2 > stream->size ) + { + FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n", + glyph_index )); + FT_TRACE0(( " end of the glyph data\n" )); + FT_TRACE0(( " is beyond the data stream\n" )); + + error = FT_THROW( Invalid_Offset ); + goto Exit; + } + else if ( off1 > off2 ) + { + FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n", + glyph_index )); + FT_TRACE0(( " the end position of glyph data\n" )); + FT_TRACE0(( " is set before the start position\n" )); + + error = FT_THROW( Invalid_Offset ); + } + + Exit: + if ( need_frame_exit ) + FT_FRAME_EXIT(); + + return error; + } + + FT_CALLBACK_DEF( FT_Error ) cid_load_glyph( T1_Decoder decoder, FT_UInt glyph_index ) @@ -97,34 +208,14 @@ else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - /* For ordinary fonts read the CID font dictionary index */ - /* and charstring offset from the CIDMap. */ { - FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; FT_ULong off1, off2; - if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + - glyph_index * entry_len ) || - FT_FRAME_ENTER( 2 * entry_len ) ) - goto Exit; - - p = (FT_Byte*)stream->cursor; - fd_select = cid_get_offset( &p, cid->fd_bytes ); - off1 = cid_get_offset( &p, cid->gd_bytes ); - p += cid->fd_bytes; - off2 = cid_get_offset( &p, cid->gd_bytes ); - FT_FRAME_EXIT(); - - if ( fd_select >= cid->num_dicts || - off2 > stream->size || - off1 > off2 ) - { - FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); - error = FT_THROW( Invalid_Offset ); + error = cid_compute_fd_and_offsets( face, glyph_index, + &fd_select, &off1, &off2 ); + if ( error ) goto Exit; - } glyph_length = off2 - off1; @@ -161,7 +252,9 @@ cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0; if ( cs_offset > glyph_length ) { - FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); + FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, " + "offset to the charstring is beyond glyph length\n", + glyph_index )); error = FT_THROW( Invalid_Offset ); goto Exit; } diff --git a/thirdparty/freetype/src/cid/cidgload.h b/thirdparty/freetype/src/cid/cidgload.h index 97954d418f..edd6229234 100644 --- a/thirdparty/freetype/src/cid/cidgload.h +++ b/thirdparty/freetype/src/cid/cidgload.h @@ -42,6 +42,14 @@ FT_BEGIN_HEADER FT_Int32 load_flags ); + FT_LOCAL( FT_Error ) + cid_compute_fd_and_offsets( CID_Face face, + FT_UInt glyph_index, + FT_ULong* fd_select_p, + FT_ULong* off1_p, + FT_ULong* off2_p ); + + FT_END_HEADER #endif /* CIDGLOAD_H_ */ diff --git a/thirdparty/freetype/src/cid/cidload.c b/thirdparty/freetype/src/cid/cidload.c index 26daa5da7f..a7da8ea39d 100644 --- a/thirdparty/freetype/src/cid/cidload.c +++ b/thirdparty/freetype/src/cid/cidload.c @@ -155,23 +155,24 @@ FT_CALLBACK_DEF( void ) - cid_parse_font_matrix( CID_Face face, - CID_Parser* parser ) + cid_parse_font_matrix( FT_Face face, /* CID_Face */ + void* parser_ ) { + CID_Face cidface = (CID_Face)face; + CID_Parser* parser = (CID_Parser*)parser_; CID_FaceDict dict; - FT_Face root = (FT_Face)&face->root; FT_Fixed temp[6]; FT_Fixed temp_scale; - if ( parser->num_dict < face->cid.num_dicts ) + if ( parser->num_dict < cidface->cid.num_dicts ) { FT_Matrix* matrix; FT_Vector* offset; FT_Int result; - dict = face->cid.font_dicts + parser->num_dict; + dict = cidface->cid.font_dicts + parser->num_dict; matrix = &dict->font_matrix; offset = &dict->font_offset; @@ -204,7 +205,7 @@ if ( temp_scale != 0x10000L ) { /* set units per EM based on FontMatrix values */ - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + face->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); temp[0] = FT_DivFix( temp[0], temp_scale ); temp[1] = FT_DivFix( temp[1], temp_scale ); @@ -237,13 +238,15 @@ FT_CALLBACK_DEF( void ) - parse_fd_array( CID_Face face, - CID_Parser* parser ) + parse_fd_array( FT_Face face, /* CID_Face */ + void* parser_ ) { - CID_FaceInfo cid = &face->cid; - FT_Memory memory = face->root.memory; - FT_Stream stream = parser->stream; - FT_Error error = FT_Err_Ok; + CID_Face cidface = (CID_Face)face; + CID_Parser* parser = (CID_Parser*)parser_; + CID_FaceInfo cid = &cidface->cid; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Stream stream = parser->stream; + FT_Error error = FT_Err_Ok; FT_Long num_dicts, max_dicts; @@ -313,18 +316,20 @@ /* By mistake, `expansion_factor' appears both in PS_PrivateRec */ /* and CID_FaceDictRec (both are public header files and can't */ - /* changed). We simply copy the value. */ + /* be thus changed). We simply copy the value. */ FT_CALLBACK_DEF( void ) - parse_expansion_factor( CID_Face face, - CID_Parser* parser ) + parse_expansion_factor( FT_Face face, /* CID_Face */ + void* parser_ ) { + CID_Face cidface = (CID_Face)face; + CID_Parser* parser = (CID_Parser*)parser_; CID_FaceDict dict; - if ( parser->num_dict < face->cid.num_dicts ) + if ( parser->num_dict < cidface->cid.num_dicts ) { - dict = face->cid.font_dicts + parser->num_dict; + dict = cidface->cid.font_dicts + parser->num_dict; dict->expansion_factor = cid_parser_to_fixed( parser, 0 ); dict->private_dict.expansion_factor = dict->expansion_factor; @@ -341,11 +346,15 @@ /* to catch it for producing better trace output. */ FT_CALLBACK_DEF( void ) - parse_font_name( CID_Face face, - CID_Parser* parser ) + parse_font_name( FT_Face face, /* CID_Face */ + void* parser_ ) { #ifdef FT_DEBUG_LEVEL_TRACE - if ( parser->num_dict < face->cid.num_dicts ) + CID_Face cidface = (CID_Face)face; + CID_Parser* parser = (CID_Parser*)parser_; + + + if ( parser->num_dict < cidface->cid.num_dicts ) { T1_TokenRec token; FT_UInt len; @@ -361,7 +370,7 @@ } #else FT_UNUSED( face ); - FT_UNUSED( parser ); + FT_UNUSED( parser_ ); #endif return; diff --git a/thirdparty/freetype/src/cid/cidobjs.c b/thirdparty/freetype/src/cid/cidobjs.c index 06b2139a93..f698a41928 100644 --- a/thirdparty/freetype/src/cid/cidobjs.c +++ b/thirdparty/freetype/src/cid/cidobjs.c @@ -69,8 +69,7 @@ FT_Module module; - module = FT_Get_Module( slot->face->driver->root.library, - "pshinter" ); + module = FT_Get_Module( slot->library, "pshinter" ); if ( module ) { T1_Hints_Funcs funcs; @@ -268,7 +267,8 @@ * * @Input: * stream :: - * The source font stream. + * Dummy argument for compatibility with the `FT_Face_InitFunc` API. + * Ignored. The stream should be passed through `face->root.stream`. * * face_index :: * The index of the font face in the resource. @@ -375,6 +375,14 @@ if ( info->is_fixed_pitch ) cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + /* + * For the sfnt-wrapped CID fonts for MacOS, currently, + * its `cmap' tables are ignored, and the content in + * its `CID ' table is treated the same as naked CID-keyed + * font. See ft_lookup_PS_in_sfnt_stream(). + */ + cidface->face_flags |= FT_FACE_FLAG_CID_KEYED; + /* XXX: TODO: add kerning with .afm support */ /* get style name -- be careful, some broken fonts only */ diff --git a/thirdparty/freetype/src/cid/cidparse.c b/thirdparty/freetype/src/cid/cidparse.c index 16889db9b6..171a886215 100644 --- a/thirdparty/freetype/src/cid/cidparse.c +++ b/thirdparty/freetype/src/cid/cidparse.c @@ -214,18 +214,24 @@ cur <= limit - STARTDATA_LEN && ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 ) { - if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) - { - FT_Long tmp = ft_strtol( (const char *)arg2, NULL, 10 ); + T1_TokenRec type_token; + FT_Long binary_length; - if ( tmp < 0 ) + parser->root.cursor = arg1; + cid_parser_to_token( parser, &type_token ); + if ( type_token.limit - type_token.start == 5 && + ft_memcmp( (char*)type_token.start, "(Hex)", 5 ) == 0 ) + { + parser->root.cursor = arg2; + binary_length = cid_parser_to_int( parser ); + if ( binary_length < 0 ) { FT_ERROR(( "cid_parser_new: invalid length of hex data\n" )); error = FT_THROW( Invalid_File_Format ); } else - parser->binary_length = (FT_ULong)tmp; + parser->binary_length = (FT_ULong)binary_length; } goto Exit; diff --git a/thirdparty/freetype/src/cid/cidriver.c b/thirdparty/freetype/src/cid/cidriver.c index f7499237d7..99e7b11839 100644 --- a/thirdparty/freetype/src/cid/cidriver.c +++ b/thirdparty/freetype/src/cid/cidriver.c @@ -48,10 +48,11 @@ * */ - static const char* - cid_get_postscript_name( CID_Face face ) + FT_CALLBACK_DEF( const char* ) + cid_get_postscript_name( FT_Face face ) /* CID_Face */ { - const char* result = face->cid.cid_font_name; + CID_Face cidface = (CID_Face)face; + const char* result = cidface->cid.cid_font_name; if ( result && result[0] == '/' ) @@ -72,34 +73,36 @@ * */ - static FT_Error - cid_ps_get_font_info( FT_Face face, + FT_CALLBACK_DEF( FT_Error ) + cid_ps_get_font_info( FT_Face face, /* CID_Face */ PS_FontInfoRec* afont_info ) { - *afont_info = ((CID_Face)face)->cid.font_info; + *afont_info = ( (CID_Face)face )->cid.font_info; return FT_Err_Ok; } - static FT_Error - cid_ps_get_font_extra( FT_Face face, - PS_FontExtraRec* afont_extra ) + + FT_CALLBACK_DEF( FT_Error ) + cid_ps_get_font_extra( FT_Face face, /* CID_Face */ + PS_FontExtraRec* afont_extra ) { - *afont_extra = ((CID_Face)face)->font_extra; + *afont_extra = ( (CID_Face)face )->font_extra; return FT_Err_Ok; } + static const FT_Service_PsInfoRec cid_service_ps_info = { - (PS_GetFontInfoFunc) cid_ps_get_font_info, /* ps_get_font_info */ - (PS_GetFontExtraFunc) cid_ps_get_font_extra, /* ps_get_font_extra */ + cid_ps_get_font_info, /* PS_GetFontInfoFunc ps_get_font_info */ + cid_ps_get_font_extra, /* PS_GetFontExtraFunc ps_get_font_extra */ /* unsupported with CID fonts */ - (PS_HasGlyphNamesFunc) NULL, /* ps_has_glyph_names */ + NULL, /* PS_HasGlyphNamesFunc ps_has_glyph_names */ /* unsupported */ - (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + NULL, /* PS_GetFontPrivateFunc ps_get_font_private */ /* not implemented */ - (PS_GetFontValueFunc) NULL /* ps_get_font_value */ + NULL /* PS_GetFontValueFunc ps_get_font_value */ }; @@ -107,13 +110,14 @@ * CID INFO SERVICE * */ - static FT_Error - cid_get_ros( CID_Face face, + FT_CALLBACK_DEF( FT_Error ) + cid_get_ros( FT_Face face, /* CID_Face */ const char* *registry, const char* *ordering, FT_Int *supplement ) { - CID_FaceInfo cid = &face->cid; + CID_Face cidface = (CID_Face)face; + CID_FaceInfo cid = &cidface->cid; if ( registry ) @@ -129,32 +133,48 @@ } - static FT_Error - cid_get_is_cid( CID_Face face, + FT_CALLBACK_DEF( FT_Error ) + cid_get_is_cid( FT_Face face, /* CID_Face */ FT_Bool *is_cid ) { FT_Error error = FT_Err_Ok; FT_UNUSED( face ); + /* + * XXX: If the ROS is Adobe-Identity-H or -V, + * the font has no reliable information about + * its glyph collection. Should we not set + * *is_cid in such cases? + */ if ( is_cid ) - *is_cid = 1; /* cid driver is only used for CID keyed fonts */ + *is_cid = 1; return error; } - static FT_Error - cid_get_cid_from_glyph_index( CID_Face face, + FT_CALLBACK_DEF( FT_Error ) + cid_get_cid_from_glyph_index( FT_Face face, /* CID_Face */ FT_UInt glyph_index, FT_UInt *cid ) { - FT_Error error = FT_Err_Ok; - FT_UNUSED( face ); - - - if ( cid ) - *cid = glyph_index; /* identity mapping */ + FT_Error error = FT_Err_Ok; + CID_Face cidface = (CID_Face)face; + + + /* + * Currently, FreeType does not support incrementally-defined, CID-keyed + * fonts that store the glyph description data in a `/GlyphDirectory` + * array or dictionary. Fonts loaded by the incremental loading feature + * are thus not handled here. + */ + error = cid_compute_fd_and_offsets( cidface, glyph_index, + NULL, NULL, NULL ); + if ( error ) + *cid = 0; + else + *cid = glyph_index; return error; } @@ -162,12 +182,12 @@ static const FT_Service_CIDRec cid_service_cid_info = { - (FT_CID_GetRegistryOrderingSupplementFunc) - cid_get_ros, /* get_ros */ - (FT_CID_GetIsInternallyCIDKeyedFunc) - cid_get_is_cid, /* get_is_cid */ - (FT_CID_GetCIDFromGlyphIndexFunc) - cid_get_cid_from_glyph_index /* get_cid_from_glyph_index */ + cid_get_ros, + /* FT_CID_GetRegistryOrderingSupplementFunc get_ros */ + cid_get_is_cid, + /* FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid */ + cid_get_cid_from_glyph_index + /* FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index */ }; @@ -179,9 +199,9 @@ FT_DEFINE_SERVICE_PROPERTIESREC( cid_service_properties, - (FT_Properties_SetFunc)ps_property_set, /* set_property */ - (FT_Properties_GetFunc)ps_property_get ) /* get_property */ - + ps_property_set, /* FT_Properties_SetFunc set_property */ + ps_property_get /* FT_Properties_GetFunc get_property */ + ) /* * SERVICE LIST @@ -209,7 +229,6 @@ } - FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec t1cid_driver_class = { diff --git a/thirdparty/freetype/src/gxvalid/gxvfgen.c b/thirdparty/freetype/src/gxvalid/gxvfgen.c index 1153542286..cf98bb36c3 100644 --- a/thirdparty/freetype/src/gxvalid/gxvfgen.c +++ b/thirdparty/freetype/src/gxvalid/gxvfgen.c @@ -97,7 +97,8 @@ #define EMPTYFEAT {0, 0, {NULL}} - static GX_Feature_RegistryRec featreg_table[] = { + static GX_Feature_RegistryRec featreg_table[] = + { { /* 0 */ "All Typographic Features", 0, diff --git a/thirdparty/freetype/src/gzip/ftgzip.c b/thirdparty/freetype/src/gzip/ftgzip.c index 48da6ff9c7..ca6a2aabe6 100644 --- a/thirdparty/freetype/src/gzip/ftgzip.c +++ b/thirdparty/freetype/src/gzip/ftgzip.c @@ -70,10 +70,9 @@ /* so that configuration with `FT_CONFIG_OPTION_SYSTEM_ZLIB' might */ /* include the wrong `zconf.h' file, leading to errors. */ -#if defined( __GNUC__ ) || defined( __clang__ ) #define ZEXPORT -#define ZEXTERN static -#endif + /* prevent zlib functions from being visible outside their object files */ +#define ZEXTERN static #define HAVE_MEMCPY 1 #define Z_SOLO 1 diff --git a/thirdparty/freetype/src/gzip/infback.c b/thirdparty/freetype/src/gzip/infback.c deleted file mode 100644 index 264c14e0df..0000000000 --- a/thirdparty/freetype/src/gzip/infback.c +++ /dev/null @@ -1,644 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_( - z_streamp strm, - int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size) -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - state->sane = 1; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables( - struct inflate_state FAR *state) -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack( - z_streamp strm, - in_func in, - void FAR *in_desc, - out_func out, - void FAR *out_desc) -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - /* fallthrough */ - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly */ - ret = Z_STREAM_END; - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: - /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Write leftover output and return unused input */ - inf_leave: - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left) && - ret == Z_STREAM_END) - ret = Z_BUF_ERROR; - } - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd( - z_streamp strm) -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/thirdparty/freetype/src/pcf/pcfdrivr.c b/thirdparty/freetype/src/pcf/pcfdrivr.c index bfa6eacca4..f1dba02404 100644 --- a/thirdparty/freetype/src/pcf/pcfdrivr.c +++ b/thirdparty/freetype/src/pcf/pcfdrivr.c @@ -75,36 +75,36 @@ THE SOFTWARE. FT_CALLBACK_DEF( FT_Error ) - pcf_cmap_init( FT_CMap pcfcmap, /* PCF_CMap */ + pcf_cmap_init( FT_CMap cmap, /* PCF_CMap */ FT_Pointer init_data ) { - PCF_CMap cmap = (PCF_CMap)pcfcmap; - PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap ); + PCF_CMap pcfcmap = (PCF_CMap)cmap; + PCF_Face face = (PCF_Face)FT_CMAP_FACE( cmap ); FT_UNUSED( init_data ); - cmap->enc = &face->enc; + pcfcmap->enc = &face->enc; return FT_Err_Ok; } FT_CALLBACK_DEF( void ) - pcf_cmap_done( FT_CMap pcfcmap ) /* PCF_CMap */ + pcf_cmap_done( FT_CMap cmap ) /* PCF_CMap */ { - PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_CMap pcfcmap = (PCF_CMap)cmap; - cmap->enc = NULL; + pcfcmap->enc = NULL; } FT_CALLBACK_DEF( FT_UInt ) - pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */ + pcf_cmap_char_index( FT_CMap cmap, /* PCF_CMap */ FT_UInt32 charcode ) { - PCF_Enc enc = ( (PCF_CMap)pcfcmap )->enc; + PCF_Enc enc = ( (PCF_CMap)cmap )->enc; FT_UInt32 i = ( charcode >> 8 ) - enc->firstRow; FT_UInt32 j = ( charcode & 0xFF ) - enc->firstCol; @@ -121,10 +121,10 @@ THE SOFTWARE. FT_CALLBACK_DEF( FT_UInt ) - pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */ + pcf_cmap_char_next( FT_CMap cmap, /* PCF_CMap */ FT_UInt32 *acharcode ) { - PCF_Enc enc = ( (PCF_CMap)pcfcmap )->enc; + PCF_Enc enc = ( (PCF_CMap)cmap )->enc; FT_UInt32 charcode = *acharcode + 1; FT_UInt32 i = ( charcode >> 8 ) - enc->firstRow; @@ -170,9 +170,9 @@ THE SOFTWARE. FT_CALLBACK_DEF( void ) - PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */ + PCF_Face_Done( FT_Face face ) /* PCF_Face */ { - PCF_Face face = (PCF_Face)pcfface; + PCF_Face pcfface = (PCF_Face)face; FT_Memory memory; @@ -181,18 +181,18 @@ THE SOFTWARE. memory = FT_FACE_MEMORY( face ); - FT_FREE( face->metrics ); - FT_FREE( face->enc.offset ); + FT_FREE( pcfface->metrics ); + FT_FREE( pcfface->enc.offset ); /* free properties */ - if ( face->properties ) + if ( pcfface->properties ) { FT_Int i; - for ( i = 0; i < face->nprops; i++ ) + for ( i = 0; i < pcfface->nprops; i++ ) { - PCF_Property prop = &face->properties[i]; + PCF_Property prop = &pcfface->properties[i]; if ( prop ) @@ -203,33 +203,33 @@ THE SOFTWARE. } } - FT_FREE( face->properties ); + FT_FREE( pcfface->properties ); } - FT_FREE( face->toc.tables ); - FT_FREE( pcfface->family_name ); - FT_FREE( pcfface->style_name ); - FT_FREE( pcfface->available_sizes ); - FT_FREE( face->charset_encoding ); - FT_FREE( face->charset_registry ); + FT_FREE( pcfface->toc.tables ); + FT_FREE( face->family_name ); + FT_FREE( face->style_name ); + FT_FREE( face->available_sizes ); + FT_FREE( pcfface->charset_encoding ); + FT_FREE( pcfface->charset_registry ); /* close compressed stream if any */ - if ( pcfface->stream == &face->comp_stream ) + if ( face->stream == &pcfface->comp_stream ) { - FT_Stream_Close( &face->comp_stream ); - pcfface->stream = face->comp_source; + FT_Stream_Close( &pcfface->comp_stream ); + face->stream = pcfface->comp_source; } } FT_CALLBACK_DEF( FT_Error ) PCF_Face_Init( FT_Stream stream, - FT_Face pcfface, /* PCF_Face */ + FT_Face face, /* PCF_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { - PCF_Face face = (PCF_Face)pcfface; + PCF_Face pcfface = (PCF_Face)face; FT_Error error; FT_UNUSED( num_params ); @@ -238,10 +238,10 @@ THE SOFTWARE. FT_TRACE2(( "PCF driver\n" )); - error = pcf_load_font( stream, face, face_index ); + error = pcf_load_font( stream, pcfface, face_index ); if ( error ) { - PCF_Face_Done( pcfface ); + PCF_Face_Done( face ); #if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ defined( FT_CONFIG_OPTION_USE_LZW ) || \ @@ -254,7 +254,7 @@ THE SOFTWARE. /* this didn't work, try gzip support! */ FT_TRACE2(( " ... try gzip stream\n" )); - error2 = FT_Stream_OpenGzip( &face->comp_stream, stream ); + error2 = FT_Stream_OpenGzip( &pcfface->comp_stream, stream ); if ( FT_ERR_EQ( error2, Unimplemented_Feature ) ) goto Fail; @@ -270,7 +270,7 @@ THE SOFTWARE. /* this didn't work, try LZW support! */ FT_TRACE2(( " ... try LZW stream\n" )); - error3 = FT_Stream_OpenLZW( &face->comp_stream, stream ); + error3 = FT_Stream_OpenLZW( &pcfface->comp_stream, stream ); if ( FT_ERR_EQ( error3, Unimplemented_Feature ) ) goto Fail; @@ -286,7 +286,7 @@ THE SOFTWARE. /* this didn't work, try Bzip2 support! */ FT_TRACE2(( " ... try Bzip2 stream\n" )); - error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream ); + error4 = FT_Stream_OpenBzip2( &pcfface->comp_stream, stream ); if ( FT_ERR_EQ( error4, Unimplemented_Feature ) ) goto Fail; @@ -297,12 +297,12 @@ THE SOFTWARE. if ( error ) goto Fail; - face->comp_source = stream; - pcfface->stream = &face->comp_stream; + pcfface->comp_source = stream; + face->stream = &pcfface->comp_stream; - stream = pcfface->stream; + stream = face->stream; - error = pcf_load_font( stream, face, face_index ); + error = pcf_load_font( stream, pcfface, face_index ); if ( error ) goto Fail; @@ -326,14 +326,14 @@ THE SOFTWARE. else if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "PCF_Face_Init: invalid face index\n" )); - PCF_Face_Done( pcfface ); + PCF_Face_Done( face ); return FT_THROW( Invalid_Argument ); } /* set up charmap */ { - FT_String *charset_registry = face->charset_registry; - FT_String *charset_encoding = face->charset_encoding; + FT_String *charset_registry = pcfface->charset_registry; + FT_String *charset_encoding = pcfface->charset_encoding; FT_Bool unicode_charmap = 0; @@ -349,13 +349,13 @@ THE SOFTWARE. ( s[2] == 'o' || s[2] == 'O' ) ) { s += 3; - if ( !ft_strcmp( s, "10646" ) || - ( !ft_strcmp( s, "8859" ) && - !ft_strcmp( face->charset_encoding, "1" ) ) ) + if ( !ft_strcmp( s, "10646" ) || + ( !ft_strcmp( s, "8859" ) && + !ft_strcmp( pcfface->charset_encoding, "1" ) ) ) unicode_charmap = 1; /* another name for ASCII */ - else if ( !ft_strcmp( s, "646.1991" ) && - !ft_strcmp( face->charset_encoding, "IRV" ) ) + else if ( !ft_strcmp( s, "646.1991" ) && + !ft_strcmp( pcfface->charset_encoding, "IRV" ) ) unicode_charmap = 1; } } @@ -364,7 +364,7 @@ THE SOFTWARE. FT_CharMapRec charmap; - charmap.face = FT_FACE( face ); + charmap.face = face; charmap.encoding = FT_ENCODING_NONE; /* initial platform/encoding should indicate unset status? */ charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; @@ -386,7 +386,7 @@ THE SOFTWARE. Fail: FT_TRACE2(( " not a PCF file\n" )); - PCF_Face_Done( pcfface ); + PCF_Face_Done( face ); error = FT_THROW( Unknown_File_Format ); /* error */ goto Exit; } @@ -569,15 +569,16 @@ THE SOFTWARE. * */ - static FT_Error - pcf_get_bdf_property( PCF_Face face, + FT_CALLBACK_DEF( FT_Error ) + pcf_get_bdf_property( FT_Face face, /* PCF_Face */ const char* prop_name, BDF_PropertyRec *aproperty ) { + PCF_Face pcfface = (PCF_Face)face; PCF_Property prop; - prop = pcf_find_property( face, prop_name ); + prop = pcf_find_property( pcfface, prop_name ); if ( prop ) { if ( prop->isString ) @@ -611,13 +612,16 @@ THE SOFTWARE. } - static FT_Error - pcf_get_charset_id( PCF_Face face, + FT_CALLBACK_DEF( FT_Error ) + pcf_get_charset_id( FT_Face face, /* PCF_Face */ const char* *acharset_encoding, const char* *acharset_registry ) { - *acharset_encoding = face->charset_encoding; - *acharset_registry = face->charset_registry; + PCF_Face pcfface = (PCF_Face)face; + + + *acharset_encoding = pcfface->charset_encoding; + *acharset_registry = pcfface->charset_registry; return FT_Err_Ok; } @@ -634,7 +638,7 @@ THE SOFTWARE. * PROPERTY SERVICE * */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) pcf_property_set( FT_Module module, /* PCF_Driver */ const char* property_name, const void* value, @@ -695,10 +699,10 @@ THE SOFTWARE. } - static FT_Error + FT_CALLBACK_DEF( FT_Error ) pcf_property_get( FT_Module module, /* PCF_Driver */ const char* property_name, - const void* value ) + void* value ) { #ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES diff --git a/thirdparty/freetype/src/pfr/pfrcmap.c b/thirdparty/freetype/src/pfr/pfrcmap.c index 312a9ffe17..08fe41d54e 100644 --- a/thirdparty/freetype/src/pfr/pfrcmap.c +++ b/thirdparty/freetype/src/pfr/pfrcmap.c @@ -24,17 +24,18 @@ FT_CALLBACK_DEF( FT_Error ) - pfr_cmap_init( PFR_CMap cmap, + pfr_cmap_init( FT_CMap cmap, /* PFR_CMap */ FT_Pointer pointer ) { - FT_Error error = FT_Err_Ok; - PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); + PFR_CMap pfrcmap = (PFR_CMap)cmap; + FT_Error error = FT_Err_Ok; + PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); FT_UNUSED( pointer ); - cmap->num_chars = face->phy_font.num_chars; - cmap->chars = face->phy_font.chars; + pfrcmap->num_chars = face->phy_font.num_chars; + pfrcmap->chars = face->phy_font.chars; /* just for safety, check that the character entries are correctly */ /* sorted in increasing character code order */ @@ -42,9 +43,9 @@ FT_UInt n; - for ( n = 1; n < cmap->num_chars; n++ ) + for ( n = 1; n < pfrcmap->num_chars; n++ ) { - if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code ) + if ( pfrcmap->chars[n - 1].char_code >= pfrcmap->chars[n].char_code ) { error = FT_THROW( Invalid_Table ); goto Exit; @@ -58,26 +59,30 @@ FT_CALLBACK_DEF( void ) - pfr_cmap_done( PFR_CMap cmap ) + pfr_cmap_done( FT_CMap cmap ) /* PFR_CMap */ { - cmap->chars = NULL; - cmap->num_chars = 0; + PFR_CMap pfrcmap = (PFR_CMap)cmap; + + + pfrcmap->chars = NULL; + pfrcmap->num_chars = 0; } FT_CALLBACK_DEF( FT_UInt ) - pfr_cmap_char_index( PFR_CMap cmap, + pfr_cmap_char_index( FT_CMap cmap, /* PFR_CMap */ FT_UInt32 char_code ) { - FT_UInt min = 0; - FT_UInt max = cmap->num_chars; - FT_UInt mid = min + ( max - min ) / 2; + PFR_CMap pfrcmap = (PFR_CMap)cmap; + FT_UInt min = 0; + FT_UInt max = pfrcmap->num_chars; + FT_UInt mid = min + ( max - min ) / 2; PFR_Char gchar; while ( min < max ) { - gchar = cmap->chars + mid; + gchar = pfrcmap->chars + mid; if ( gchar->char_code == char_code ) return mid + 1; @@ -96,10 +101,11 @@ } - FT_CALLBACK_DEF( FT_UInt32 ) - pfr_cmap_char_next( PFR_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + pfr_cmap_char_next( FT_CMap cmap, /* PFR_CMap */ FT_UInt32 *pchar_code ) { + PFR_CMap pfrcmap = (PFR_CMap)cmap; FT_UInt result = 0; FT_UInt32 char_code = *pchar_code + 1; @@ -107,14 +113,14 @@ Restart: { FT_UInt min = 0; - FT_UInt max = cmap->num_chars; + FT_UInt max = pfrcmap->num_chars; FT_UInt mid = min + ( max - min ) / 2; PFR_Char gchar; while ( min < max ) { - gchar = cmap->chars + mid; + gchar = pfrcmap->chars + mid; if ( gchar->char_code == char_code ) { @@ -143,9 +149,9 @@ /* we didn't find it, but we have a pair just above it */ char_code = 0; - if ( min < cmap->num_chars ) + if ( min < pfrcmap->num_chars ) { - gchar = cmap->chars + min; + gchar = pfrcmap->chars + min; result = min; if ( result != 0 ) { diff --git a/thirdparty/freetype/src/pfr/pfrdrivr.c b/thirdparty/freetype/src/pfr/pfrdrivr.c index 78c6c6882c..0048f52411 100644 --- a/thirdparty/freetype/src/pfr/pfrdrivr.c +++ b/thirdparty/freetype/src/pfr/pfrdrivr.c @@ -27,16 +27,16 @@ FT_CALLBACK_DEF( FT_Error ) - pfr_get_kerning( FT_Face pfrface, /* PFR_Face */ + pfr_get_kerning( FT_Face face, /* PFR_Face */ FT_UInt left, FT_UInt right, FT_Vector *avector ) { - PFR_Face face = (PFR_Face)pfrface; - PFR_PhyFont phys = &face->phy_font; + PFR_Face pfrface = (PFR_Face)face; + PFR_PhyFont phys = &pfrface->phy_font; - (void)pfr_face_get_kerning( pfrface, left, right, avector ); + (void)pfr_face_get_kerning( face, left, right, avector ); /* convert from metrics to outline units when necessary */ if ( phys->outline_resolution != phys->metrics_resolution ) @@ -62,12 +62,12 @@ */ FT_CALLBACK_DEF( FT_Error ) - pfr_get_advance( FT_Face pfrface, /* PFR_Face */ + pfr_get_advance( FT_Face face, /* PFR_Face */ FT_UInt gindex, FT_Pos *anadvance ) { - PFR_Face face = (PFR_Face)pfrface; - FT_Error error = FT_ERR( Invalid_Argument ); + PFR_Face pfrface = (PFR_Face)face; + FT_Error error = FT_ERR( Invalid_Argument ); *anadvance = 0; @@ -77,9 +77,9 @@ gindex--; - if ( face ) + if ( pfrface ) { - PFR_PhyFont phys = &face->phy_font; + PFR_PhyFont phys = &pfrface->phy_font; if ( gindex < phys->num_chars ) @@ -95,16 +95,16 @@ FT_CALLBACK_DEF( FT_Error ) - pfr_get_metrics( FT_Face pfrface, /* PFR_Face */ + pfr_get_metrics( FT_Face face, /* PFR_Face */ FT_UInt *anoutline_resolution, FT_UInt *ametrics_resolution, FT_Fixed *ametrics_x_scale, FT_Fixed *ametrics_y_scale ) { - PFR_Face face = (PFR_Face)pfrface; - PFR_PhyFont phys = &face->phy_font; + PFR_Face pfrface = (PFR_Face)face; + PFR_PhyFont phys = &pfrface->phy_font; FT_Fixed x_scale, y_scale; - FT_Size size = face->root.size; + FT_Size size = pfrface->root.size; if ( anoutline_resolution ) diff --git a/thirdparty/freetype/src/pfr/pfrgload.c b/thirdparty/freetype/src/pfr/pfrgload.c index 14f2ec3778..48cf27ec80 100644 --- a/thirdparty/freetype/src/pfr/pfrgload.c +++ b/thirdparty/freetype/src/pfr/pfrgload.c @@ -560,8 +560,7 @@ FT_Byte* limit ) { FT_Error error = FT_Err_Ok; - FT_GlyphLoader loader = glyph->loader; - FT_Memory memory = loader->memory; + FT_Memory memory = glyph->loader->memory; PFR_SubGlyph subglyph; FT_UInt flags, i, count, org_count; FT_Int x_pos, y_pos; diff --git a/thirdparty/freetype/src/pfr/pfrload.c b/thirdparty/freetype/src/pfr/pfrload.c index de85ee6aad..856a5942f5 100644 --- a/thirdparty/freetype/src/pfr/pfrload.c +++ b/thirdparty/freetype/src/pfr/pfrload.c @@ -449,15 +449,16 @@ /* load bitmap strikes lists */ FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_bitmap_info( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) + pfr_extra_item_load_bitmap_info( FT_Byte* p, + FT_Byte* limit, + void* phy_font_ ) { - FT_Memory memory = phy_font->memory; - PFR_Strike strike; - FT_UInt flags0; - FT_UInt n, count, size1; - FT_Error error = FT_Err_Ok; + PFR_PhyFont phy_font = (PFR_PhyFont)phy_font_; + FT_Memory memory = phy_font->memory; + PFR_Strike strike; + FT_UInt flags0; + FT_UInt n, count, size1; + FT_Error error = FT_Err_Ok; PFR_CHECK( 5 ); @@ -549,13 +550,14 @@ * family. */ FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_font_id( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) + pfr_extra_item_load_font_id( FT_Byte* p, + FT_Byte* limit, + void* phy_font_ ) { - FT_Error error = FT_Err_Ok; - FT_Memory memory = phy_font->memory; - FT_UInt len = (FT_UInt)( limit - p ); + PFR_PhyFont phy_font = (PFR_PhyFont)phy_font_; + FT_Error error = FT_Err_Ok; + FT_Memory memory = phy_font->memory; + FT_UInt len = (FT_UInt)( limit - p ); if ( phy_font->font_id ) @@ -575,14 +577,15 @@ /* load stem snap tables */ FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_stem_snaps( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) + pfr_extra_item_load_stem_snaps( FT_Byte* p, + FT_Byte* limit, + void* phy_font_ ) { - FT_UInt count, num_vert, num_horz; - FT_Int* snaps = NULL; - FT_Error error = FT_Err_Ok; - FT_Memory memory = phy_font->memory; + PFR_PhyFont phy_font = (PFR_PhyFont)phy_font_; + FT_UInt count, num_vert, num_horz; + FT_Int* snaps = NULL; + FT_Error error = FT_Err_Ok; + FT_Memory memory = phy_font->memory; if ( phy_font->vertical.stem_snaps ) @@ -619,10 +622,11 @@ /* load kerning pair data */ FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_kerning_pairs( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) + pfr_extra_item_load_kerning_pairs( FT_Byte* p, + FT_Byte* limit, + void* phy_font_ ) { + PFR_PhyFont phy_font = (PFR_PhyFont)phy_font_; PFR_KernItem item = NULL; FT_Error error = FT_Err_Ok; FT_Memory memory = phy_font->memory; @@ -715,10 +719,10 @@ static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = { - { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, - { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id }, - { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps }, - { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs }, + { 1, pfr_extra_item_load_bitmap_info }, + { 2, pfr_extra_item_load_font_id }, + { 3, pfr_extra_item_load_stem_snaps }, + { 4, pfr_extra_item_load_kerning_pairs }, { 0, NULL } }; diff --git a/thirdparty/freetype/src/pfr/pfrobjs.c b/thirdparty/freetype/src/pfr/pfrobjs.c index 3db8f0a060..8ef17c6636 100644 --- a/thirdparty/freetype/src/pfr/pfrobjs.c +++ b/thirdparty/freetype/src/pfr/pfrobjs.c @@ -50,14 +50,14 @@ if ( !face ) return; - memory = pfrface->driver->root.memory; + memory = pfrface->memory; /* we don't want dangling pointers */ pfrface->family_name = NULL; pfrface->style_name = NULL; /* finalize the physical font record */ - pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); + pfr_phy_font_done( &face->phy_font, memory ); /* no need to finalize the logical font or the header */ FT_FREE( pfrface->available_sizes ); @@ -214,7 +214,7 @@ FT_UInt n, count = phy_font->num_strikes; FT_Bitmap_Size* size; PFR_Strike strike; - FT_Memory memory = pfrface->stream->memory; + FT_Memory memory = pfrface->memory; if ( FT_QNEW_ARRAY( pfrface->available_sizes, count ) ) diff --git a/thirdparty/freetype/src/psaux/afmparse.c b/thirdparty/freetype/src/psaux/afmparse.c index 68f95698e6..db08941def 100644 --- a/thirdparty/freetype/src/psaux/afmparse.c +++ b/thirdparty/freetype/src/psaux/afmparse.c @@ -1086,7 +1086,7 @@ #else /* T1_CONFIG_OPTION_NO_AFM */ /* ANSI C doesn't like empty source files */ - typedef int _afm_parse_dummy; + typedef int afm_parse_dummy_; #endif /* T1_CONFIG_OPTION_NO_AFM */ diff --git a/thirdparty/freetype/src/psaux/t1cmap.c b/thirdparty/freetype/src/psaux/t1cmap.c index bf0a393b45..c4bcf599ea 100644 --- a/thirdparty/freetype/src/psaux/t1cmap.c +++ b/thirdparty/freetype/src/psaux/t1cmap.c @@ -50,8 +50,11 @@ FT_CALLBACK_DEF( void ) - t1_cmap_std_done( T1_CMapStd cmap ) + t1_cmap_std_done( FT_CMap cmap_ ) /* T1_CMapStd */ { + T1_CMapStd cmap = (T1_CMapStd)cmap_; + + cmap->num_glyphs = 0; cmap->glyph_names = NULL; cmap->sid_to_string = NULL; @@ -60,10 +63,11 @@ FT_CALLBACK_DEF( FT_UInt ) - t1_cmap_std_char_index( T1_CMapStd cmap, - FT_UInt32 char_code ) + t1_cmap_std_char_index( FT_CMap cmap, /* T1_CMapStd */ + FT_UInt32 char_code ) { - FT_UInt result = 0; + T1_CMapStd t1cmap = (T1_CMapStd)cmap; + FT_UInt result = 0; if ( char_code < 256 ) @@ -73,13 +77,13 @@ /* convert character code to Adobe SID string */ - code = cmap->code_to_sid[char_code]; - glyph_name = cmap->sid_to_string( code ); + code = t1cmap->code_to_sid[char_code]; + glyph_name = t1cmap->sid_to_string( code ); /* look for the corresponding glyph name */ - for ( n = 0; n < cmap->num_glyphs; n++ ) + for ( n = 0; n < t1cmap->num_glyphs; n++ ) { - const char* gname = cmap->glyph_names[n]; + const char* gname = t1cmap->glyph_names[n]; if ( gname && gname[0] == glyph_name[0] && @@ -95,9 +99,9 @@ } - FT_CALLBACK_DEF( FT_UInt32 ) - t1_cmap_std_char_next( T1_CMapStd cmap, - FT_UInt32 *pchar_code ) + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_std_char_next( FT_CMap cmap, + FT_UInt32 *pchar_code ) { FT_UInt result = 0; FT_UInt32 char_code = *pchar_code + 1; @@ -120,13 +124,14 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_standard_init( T1_CMapStd cmap, + t1_cmap_standard_init( FT_CMap cmap, /* T1_CMapStd */ FT_Pointer pointer ) { + T1_CMapStd t1cmap = (T1_CMapStd)cmap; FT_UNUSED( pointer ); - t1_cmap_std_init( cmap, 0 ); + t1_cmap_std_init( t1cmap, 0 ); return 0; } @@ -150,13 +155,14 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_expert_init( T1_CMapStd cmap, + t1_cmap_expert_init( FT_CMap cmap, /* T1_CMapStd */ FT_Pointer pointer ) { + T1_CMapStd t1cmap = (T1_CMapStd)cmap; FT_UNUSED( pointer ); - t1_cmap_std_init( cmap, 1 ); + t1_cmap_std_init( t1cmap, 1 ); return 0; } @@ -188,20 +194,21 @@ FT_CALLBACK_DEF( FT_Error ) - t1_cmap_custom_init( T1_CMapCustom cmap, - FT_Pointer pointer ) + t1_cmap_custom_init( FT_CMap cmap, /* T1_CMapCustom */ + FT_Pointer pointer ) { - T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); - T1_Encoding encoding = &face->type1.encoding; + T1_CMapCustom t1cmap = (T1_CMapCustom)cmap; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + T1_Encoding encoding = &face->type1.encoding; FT_UNUSED( pointer ); - cmap->first = (FT_UInt)encoding->code_first; - cmap->count = (FT_UInt)encoding->code_last - cmap->first; - cmap->indices = encoding->char_index; + t1cmap->first = (FT_UInt)encoding->code_first; + t1cmap->count = (FT_UInt)encoding->code_last - t1cmap->first; + t1cmap->indices = encoding->char_index; - FT_ASSERT( cmap->indices ); + FT_ASSERT( t1cmap->indices ); FT_ASSERT( encoding->code_first <= encoding->code_last ); return 0; @@ -209,45 +216,50 @@ FT_CALLBACK_DEF( void ) - t1_cmap_custom_done( T1_CMapCustom cmap ) + t1_cmap_custom_done( FT_CMap cmap ) /* T1_CMapCustom */ { - cmap->indices = NULL; - cmap->first = 0; - cmap->count = 0; + T1_CMapCustom t1cmap = (T1_CMapCustom)cmap; + + + t1cmap->indices = NULL; + t1cmap->first = 0; + t1cmap->count = 0; } FT_CALLBACK_DEF( FT_UInt ) - t1_cmap_custom_char_index( T1_CMapCustom cmap, - FT_UInt32 char_code ) + t1_cmap_custom_char_index( FT_CMap cmap, /* T1_CMapCustom */ + FT_UInt32 char_code ) { - FT_UInt result = 0; + T1_CMapCustom t1cmap = (T1_CMapCustom)cmap; + FT_UInt result = 0; - if ( ( char_code >= cmap->first ) && - ( char_code < ( cmap->first + cmap->count ) ) ) - result = cmap->indices[char_code]; + if ( char_code >= t1cmap->first && + char_code < ( t1cmap->first + t1cmap->count ) ) + result = t1cmap->indices[char_code]; return result; } - FT_CALLBACK_DEF( FT_UInt32 ) - t1_cmap_custom_char_next( T1_CMapCustom cmap, - FT_UInt32 *pchar_code ) + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_custom_char_next( FT_CMap cmap, /* T1_CMapCustom */ + FT_UInt32 *pchar_code ) { - FT_UInt result = 0; - FT_UInt32 char_code = *pchar_code; + T1_CMapCustom t1cmap = (T1_CMapCustom)cmap; + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code; char_code++; - if ( char_code < cmap->first ) - char_code = cmap->first; + if ( char_code < t1cmap->first ) + char_code = t1cmap->first; - for ( ; char_code < ( cmap->first + cmap->count ); char_code++ ) + for ( ; char_code < ( t1cmap->first + t1cmap->count ); char_code++ ) { - result = cmap->indices[char_code]; + result = t1cmap->indices[char_code]; if ( result != 0 ) goto Exit; } @@ -287,20 +299,24 @@ /*************************************************************************/ FT_CALLBACK_DEF( const char * ) - psaux_get_glyph_name( T1_Face face, + psaux_get_glyph_name( void* face_, FT_UInt idx ) { + T1_Face face = (T1_Face)face_; + + return face->type1.glyph_names[idx]; } FT_CALLBACK_DEF( FT_Error ) - t1_cmap_unicode_init( PS_Unicodes unicodes, - FT_Pointer pointer ) + t1_cmap_unicode_init( FT_CMap cmap, /* PS_Unicodes */ + FT_Pointer pointer ) { - T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; FT_UNUSED( pointer ); @@ -311,17 +327,18 @@ return psnames->unicodes_init( memory, unicodes, (FT_UInt)face->type1.num_glyphs, - (PS_GetGlyphNameFunc)&psaux_get_glyph_name, + &psaux_get_glyph_name, (PS_FreeGlyphNameFunc)NULL, (FT_Pointer)face ); } FT_CALLBACK_DEF( void ) - t1_cmap_unicode_done( PS_Unicodes unicodes ) + t1_cmap_unicode_done( FT_CMap cmap ) /* PS_Unicodes */ { - FT_Face face = FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); + PS_Unicodes unicodes = (PS_Unicodes)cmap; + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( unicodes->maps ); @@ -330,23 +347,25 @@ FT_CALLBACK_DEF( FT_UInt ) - t1_cmap_unicode_char_index( PS_Unicodes unicodes, - FT_UInt32 char_code ) + t1_cmap_unicode_char_index( FT_CMap cmap, /* PS_Unicodes */ + FT_UInt32 char_code ) { - T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; return psnames->unicodes_char_index( unicodes, char_code ); } - FT_CALLBACK_DEF( FT_UInt32 ) - t1_cmap_unicode_char_next( PS_Unicodes unicodes, - FT_UInt32 *pchar_code ) + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_unicode_char_next( FT_CMap cmap, /* PS_Unicodes */ + FT_UInt32 *pchar_code ) { - T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; return psnames->unicodes_char_next( unicodes, pchar_code ); diff --git a/thirdparty/freetype/src/pshinter/pshalgo.c b/thirdparty/freetype/src/pshinter/pshalgo.c index a7f321291a..4f622e1e44 100644 --- a/thirdparty/freetype/src/pshinter/pshalgo.c +++ b/thirdparty/freetype/src/pshinter/pshalgo.c @@ -516,7 +516,7 @@ if ( !psh_hint_is_fitted( parent ) ) psh_hint_align( parent, globals, dimension, glyph ); - /* keep original relation between hints, this is, use the */ + /* keep original relation between hints, that is, use the */ /* scaled distance between the centers of the hints to */ /* compute the new position */ par_org_center = parent->org_pos + ( parent->org_len >> 1 ); diff --git a/thirdparty/freetype/src/pshinter/pshmod.c b/thirdparty/freetype/src/pshinter/pshmod.c index a12e485660..974a99e018 100644 --- a/thirdparty/freetype/src/pshinter/pshmod.c +++ b/thirdparty/freetype/src/pshinter/pshmod.c @@ -37,8 +37,11 @@ /* finalize module */ FT_CALLBACK_DEF( void ) - ps_hinter_done( PS_Hinter_Module module ) + ps_hinter_done( FT_Module module_ ) /* PS_Hinter_Module */ { + PS_Hinter_Module module = (PS_Hinter_Module)module_; + + module->t1_funcs.hints = NULL; module->t2_funcs.hints = NULL; @@ -48,8 +51,10 @@ /* initialize module, create hints recorder and the interface */ FT_CALLBACK_DEF( FT_Error ) - ps_hinter_init( PS_Hinter_Module module ) + ps_hinter_init( FT_Module module_ ) /* PS_Hinter_Module */ { + PS_Hinter_Module module = (PS_Hinter_Module)module_; + FT_Memory memory = module->root.memory; void* ph = &module->ps_hints; diff --git a/thirdparty/freetype/src/pshinter/pshrec.c b/thirdparty/freetype/src/pshinter/pshrec.c index 58c8cf1b48..680e6d0135 100644 --- a/thirdparty/freetype/src/pshinter/pshrec.c +++ b/thirdparty/freetype/src/pshinter/pshrec.c @@ -851,10 +851,11 @@ /* add one Type1 counter stem to the current hints table */ static void - ps_hints_t1stem3( PS_Hints hints, + ps_hints_t1stem3( T1_Hints hints_, /* PS_Hints */ FT_UInt dimension, FT_Fixed* stems ) { + PS_Hints hints = (PS_Hints)hints_; FT_Error error = FT_Err_Ok; @@ -914,9 +915,10 @@ /* reset hints (only with Type 1 hints) */ static void - ps_hints_t1reset( PS_Hints hints, + ps_hints_t1reset( T1_Hints hints_, /* PS_Hints */ FT_UInt end_point ) { + PS_Hints hints = (PS_Hints)hints_; FT_Error error = FT_Err_Ok; @@ -953,11 +955,12 @@ /* Type2 "hintmask" operator, add a new hintmask to each direction */ static void - ps_hints_t2mask( PS_Hints hints, + ps_hints_t2mask( T2_Hints hints_, /* PS_Hints */ FT_UInt end_point, FT_UInt bit_count, const FT_Byte* bytes ) { + PS_Hints hints = (PS_Hints)hints_; FT_Error error; @@ -999,10 +1002,11 @@ static void - ps_hints_t2counter( PS_Hints hints, + ps_hints_t2counter( T2_Hints hints_, /* PS_Hints */ FT_UInt bit_count, const FT_Byte* bytes ) { + PS_Hints hints = (PS_Hints)hints_; FT_Error error; @@ -1087,6 +1091,13 @@ ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 ); } + static FT_Error + t1_hints_close( T1_Hints hints, + FT_UInt end_point ) + { + return ps_hints_close( (PS_Hints)hints, end_point ); + } + static void t1_hints_stem( T1_Hints hints, FT_UInt dimension, @@ -1102,17 +1113,27 @@ } + static FT_Error + t1_hints_apply( T1_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) + { + return ps_hints_apply( (PS_Hints)hints, outline, globals, hint_mode ); + } + + FT_LOCAL_DEF( void ) t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ) { FT_ZERO( funcs ); funcs->open = (T1_Hints_OpenFunc) t1_hints_open; - funcs->close = (T1_Hints_CloseFunc) ps_hints_close; + funcs->close = (T1_Hints_CloseFunc) t1_hints_close; funcs->stem = (T1_Hints_SetStemFunc) t1_hints_stem; funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3; funcs->reset = (T1_Hints_ResetFunc) ps_hints_t1reset; - funcs->apply = (T1_Hints_ApplyFunc) ps_hints_apply; + funcs->apply = (T1_Hints_ApplyFunc) t1_hints_apply; } @@ -1131,6 +1152,14 @@ } + static FT_Error + t2_hints_close( T2_Hints hints, + FT_UInt end_point ) + { + return ps_hints_close( (PS_Hints)hints, end_point ); + } + + static void t2_hints_stems( T2_Hints hints, FT_UInt dimension, @@ -1168,17 +1197,27 @@ } + static FT_Error + t2_hints_apply( T2_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) + { + return ps_hints_apply( (PS_Hints)hints, outline, globals, hint_mode ); + } + + FT_LOCAL_DEF( void ) t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ) { FT_ZERO( funcs ); - funcs->open = (T2_Hints_OpenFunc) t2_hints_open; - funcs->close = (T2_Hints_CloseFunc) ps_hints_close; - funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; - funcs->hintmask= (T2_Hints_MaskFunc) ps_hints_t2mask; - funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter; - funcs->apply = (T2_Hints_ApplyFunc) ps_hints_apply; + funcs->open = (T2_Hints_OpenFunc) t2_hints_open; + funcs->close = (T2_Hints_CloseFunc) t2_hints_close; + funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; + funcs->hintmask = (T2_Hints_MaskFunc) ps_hints_t2mask; + funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter; + funcs->apply = (T2_Hints_ApplyFunc) t2_hints_apply; } diff --git a/thirdparty/freetype/src/psnames/psmodule.c b/thirdparty/freetype/src/psnames/psmodule.c index db454e558e..8203a0465d 100644 --- a/thirdparty/freetype/src/psnames/psmodule.c +++ b/thirdparty/freetype/src/psnames/psmodule.c @@ -57,7 +57,7 @@ /* the name, as in `A.swash' or `e.final'; in this case, the */ /* VARIANT_BIT is set in the return value. */ /* */ - static FT_UInt32 + FT_CALLBACK_DEF( FT_UInt32 ) ps_unicode_value( const char* glyph_name ) { /* If the name begins with `uni', then the glyph name may be a */ @@ -309,7 +309,7 @@ /* Build a table that maps Unicode values to glyph indices. */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) ps_unicodes_init( FT_Memory memory, PS_Unicodes table, FT_UInt num_glyphs, @@ -408,7 +408,7 @@ } - static FT_UInt + FT_CALLBACK_DEF( FT_UInt ) ps_unicodes_char_index( PS_Unicodes table, FT_UInt32 unicode ) { @@ -453,7 +453,7 @@ } - static FT_UInt32 + FT_CALLBACK_DEF( FT_UInt ) ps_unicodes_char_next( PS_Unicodes table, FT_UInt32 *unicode ) { @@ -518,7 +518,7 @@ #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - static const char* + FT_CALLBACK_DEF( const char* ) ps_get_macintosh_name( FT_UInt name_index ) { if ( name_index >= FT_NUM_MAC_NAMES ) @@ -528,7 +528,7 @@ } - static const char* + FT_CALLBACK_DEF( const char* ) ps_get_standard_strings( FT_UInt sid ) { if ( sid >= FT_NUM_SID_NAMES ) @@ -543,13 +543,13 @@ FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - (PS_Unicode_ValueFunc) ps_unicode_value, /* unicode_value */ - (PS_Unicodes_InitFunc) ps_unicodes_init, /* unicodes_init */ - (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, /* unicodes_char_index */ - (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, /* unicodes_char_next */ + ps_unicode_value, /* PS_Unicode_ValueFunc unicode_value */ + ps_unicodes_init, /* PS_Unicodes_InitFunc unicodes_init */ + ps_unicodes_char_index, /* PS_Unicodes_CharIndexFunc unicodes_char_index */ + ps_unicodes_char_next, /* PS_Unicodes_CharNextFunc unicodes_char_next */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ + ps_get_macintosh_name, /* PS_Macintosh_NameFunc macintosh_name */ + ps_get_standard_strings, /* PS_Adobe_Std_StringsFunc adobe_std_strings */ t1_standard_encoding, /* adobe_std_encoding */ t1_expert_encoding /* adobe_expert_encoding */ @@ -560,13 +560,13 @@ FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - NULL, /* unicode_value */ - NULL, /* unicodes_init */ - NULL, /* unicodes_char_index */ - NULL, /* unicodes_char_next */ + NULL, /* PS_Unicode_ValueFunc unicode_value */ + NULL, /* PS_Unicodes_InitFunc unicodes_init */ + NULL, /* PS_Unicodes_CharIndexFunc unicodes_char_index */ + NULL, /* PS_Unicodes_CharNextFunc unicodes_char_next */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ + ps_get_macintosh_name, /* PS_Macintosh_NameFunc macintosh_name */ + ps_get_standard_strings, /* PS_Adobe_Std_StringsFunc adobe_std_strings */ t1_standard_encoding, /* adobe_std_encoding */ t1_expert_encoding /* adobe_expert_encoding */ @@ -612,9 +612,9 @@ PUT_PS_NAMES_SERVICE( (void*)&pscmaps_interface ), /* module specific interface */ - (FT_Module_Constructor)NULL, /* module_init */ - (FT_Module_Destructor) NULL, /* module_done */ - (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) /* get_interface */ + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ + PUT_PS_NAMES_SERVICE( psnames_get_service ) /* FT_Module_Requester get_interface */ ) diff --git a/thirdparty/freetype/src/raster/ftraster.c b/thirdparty/freetype/src/raster/ftraster.c index 67cbfd5d9b..192ca0701a 100644 --- a/thirdparty/freetype/src/raster/ftraster.c +++ b/thirdparty/freetype/src/raster/ftraster.c @@ -1742,9 +1742,9 @@ * SUCCESS on success, FAILURE on error. */ static Bool - Decompose_Curve( RAS_ARGS UShort first, - UShort last, - Int flipped ) + Decompose_Curve( RAS_ARGS Int first, + Int last, + Int flipped ) { FT_Vector v_last; FT_Vector v_control; @@ -1969,8 +1969,8 @@ static Bool Convert_Glyph( RAS_ARGS Int flipped ) { - Int i; - UInt start; + Int i; + Int first, last; ras.fProfile = NULL; @@ -1985,8 +1985,7 @@ ras.cProfile->offset = ras.top; ras.num_Profs = 0; - start = 0; - + last = -1; for ( i = 0; i < ras.outline.n_contours; i++ ) { PProfile lastProfile; @@ -1996,12 +1995,11 @@ ras.state = Unknown_State; ras.gProfile = NULL; - if ( Decompose_Curve( RAS_VARS (UShort)start, - (UShort)ras.outline.contours[i], - flipped ) ) - return FAILURE; + first = last + 1; + last = ras.outline.contours[i]; - start = (UShort)ras.outline.contours[i] + 1; + if ( Decompose_Curve( RAS_VARS first, last, flipped ) ) + return FAILURE; /* we must now check whether the extreme arcs join or not */ if ( FRAC( ras.lastY ) == 0 && @@ -3167,9 +3165,12 @@ static int - ft_black_new( FT_Memory memory, - black_PRaster *araster ) + ft_black_new( void* memory_, /* FT_Memory */ + FT_Raster *araster_ ) /* black_PRaster */ { + FT_Memory memory = (FT_Memory)memory_; + black_PRaster *araster = (black_PRaster*)araster_; + FT_Error error; black_PRaster raster = NULL; @@ -3184,9 +3185,10 @@ static void - ft_black_done( black_PRaster raster ) + ft_black_done( FT_Raster raster_ ) /* black_PRaster */ { - FT_Memory memory = (FT_Memory)raster->memory; + black_PRaster raster = (black_PRaster)raster_; + FT_Memory memory = (FT_Memory)raster->memory; FT_FREE( raster ); @@ -3281,11 +3283,11 @@ FT_GLYPH_FORMAT_OUTLINE, - (FT_Raster_New_Func) ft_black_new, /* raster_new */ - (FT_Raster_Reset_Func) ft_black_reset, /* raster_reset */ - (FT_Raster_Set_Mode_Func)ft_black_set_mode, /* raster_set_mode */ - (FT_Raster_Render_Func) ft_black_render, /* raster_render */ - (FT_Raster_Done_Func) ft_black_done /* raster_done */ + ft_black_new, /* FT_Raster_New_Func raster_new */ + ft_black_reset, /* FT_Raster_Reset_Func raster_reset */ + ft_black_set_mode, /* FT_Raster_Set_Mode_Func raster_set_mode */ + ft_black_render, /* FT_Raster_Render_Func raster_render */ + ft_black_done /* FT_Raster_Done_Func raster_done */ ) diff --git a/thirdparty/freetype/src/raster/ftrend1.c b/thirdparty/freetype/src/raster/ftrend1.c index 0b5d867147..6d442b1ff8 100644 --- a/thirdparty/freetype/src/raster/ftrend1.c +++ b/thirdparty/freetype/src/raster/ftrend1.c @@ -27,8 +27,11 @@ /* initialize renderer -- init its raster */ static FT_Error - ft_raster1_init( FT_Renderer render ) + ft_raster1_init( FT_Module module ) /* FT_Renderer */ { + FT_Renderer render = (FT_Renderer)module; + + render->clazz->raster_class->raster_reset( render->raster, NULL, 0 ); return FT_Err_Ok; @@ -188,18 +191,18 @@ NULL, /* module specific interface */ - (FT_Module_Constructor)ft_raster1_init, /* module_init */ - (FT_Module_Destructor) NULL, /* module_done */ - (FT_Module_Requester) NULL, /* get_interface */ + ft_raster1_init, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ + NULL, /* FT_Module_Requester get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_raster1_render, /* render_glyph */ - (FT_Renderer_TransformFunc)ft_raster1_transform, /* transform_glyph */ - (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, /* get_glyph_cbox */ - (FT_Renderer_SetModeFunc) ft_raster1_set_mode, /* set_mode */ + ft_raster1_render, /* FT_Renderer_RenderFunc render_glyph */ + ft_raster1_transform, /* FT_Renderer_TransformFunc transform_glyph */ + ft_raster1_get_cbox, /* FT_Renderer_GetCBoxFunc get_glyph_cbox */ + ft_raster1_set_mode, /* FT_Renderer_SetModeFunc set_mode */ - (FT_Raster_Funcs*)&ft_standard_raster /* raster_class */ + &ft_standard_raster /* FT_Raster_Funcs* raster_class */ ) diff --git a/thirdparty/freetype/src/sdf/ftbsdf.c b/thirdparty/freetype/src/sdf/ftbsdf.c index 901d8b7402..e472738339 100644 --- a/thirdparty/freetype/src/sdf/ftbsdf.c +++ b/thirdparty/freetype/src/sdf/ftbsdf.c @@ -1173,9 +1173,12 @@ /* called when adding a new module through @FT_Add_Module */ static FT_Error - bsdf_raster_new( FT_Memory memory, - BSDF_PRaster* araster ) + bsdf_raster_new( void* memory_, /* FT_Memory */ + FT_Raster* araster_ ) /* BSDF_PRaster* */ { + FT_Memory memory = (FT_Memory)memory_; + BSDF_PRaster* araster = (BSDF_PRaster*)araster_; + FT_Error error; BSDF_PRaster raster = NULL; diff --git a/thirdparty/freetype/src/sdf/ftsdf.c b/thirdparty/freetype/src/sdf/ftsdf.c index 26a6d00e4a..bc4625d984 100644 --- a/thirdparty/freetype/src/sdf/ftsdf.c +++ b/thirdparty/freetype/src/sdf/ftsdf.c @@ -2371,11 +2371,11 @@ * ``` * * (6) Our task is to find a value of `t` such that the above equation - * `Q(t)` becomes zero, this is, the point-to-curve vector makes + * `Q(t)` becomes zero, that is, the point-to-curve vector makes * 90~degrees with the curve. We solve this with the Newton-Raphson * method. * - * (7) We first assume an arbitary value of factor `t`, which we then + * (7) We first assume an arbitrary value of factor `t`, which we then * improve. * * ``` @@ -2684,11 +2684,11 @@ * ``` * * (6) Our task is to find a value of `t` such that the above equation - * `Q(t)` becomes zero, this is, the point-to-curve vector makes + * `Q(t)` becomes zero, that is, the point-to-curve vector makes * 90~degree with curve. We solve this with the Newton-Raphson * method. * - * (7) We first assume an arbitary value of factor `t`, which we then + * (7) We first assume an arbitrary value of factor `t`, which we then * improve. * * ``` @@ -2718,8 +2718,9 @@ FT_Error error = FT_Err_Ok; - FT_26D6_Vec aA, bB, cC, dD; /* A, B, C in the above comment */ - FT_16D16_Vec nearest_point; /* point on curve nearest to `point` */ + FT_26D6_Vec aA, bB, cC, dD; /* A, B, C, D in the above comment */ + FT_16D16_Vec nearest_point = { 0, 0 }; + /* point on curve nearest to `point` */ FT_16D16_Vec direction; /* direction of curve at `nearest_point` */ FT_26D6_Vec p0, p1, p2, p3; /* control points of a cubic curve */ @@ -3761,9 +3762,13 @@ */ static FT_Error - sdf_raster_new( FT_Memory memory, - SDF_PRaster* araster ) + sdf_raster_new( void* memory_, /* FT_Memory */ + FT_Raster* araster_ ) /* SDF_PRaster* */ { + FT_Memory memory = (FT_Memory)memory_; + SDF_PRaster* araster = (SDF_PRaster*)araster_; + + FT_Error error; SDF_PRaster raster = NULL; diff --git a/thirdparty/freetype/src/sdf/ftsdfrend.c b/thirdparty/freetype/src/sdf/ftsdfrend.c index 9ac7d6f620..5610c119f8 100644 --- a/thirdparty/freetype/src/sdf/ftsdfrend.c +++ b/thirdparty/freetype/src/sdf/ftsdfrend.c @@ -197,10 +197,10 @@ static FT_Module_Interface - ft_sdf_requester( FT_Renderer render, + ft_sdf_requester( FT_Module module, const char* module_interface ) { - FT_UNUSED( render ); + FT_UNUSED( module ); return ft_service_list_lookup( sdf_services, module_interface ); } @@ -221,9 +221,9 @@ */ static FT_Error - ft_sdf_init( FT_Renderer render ) + ft_sdf_init( FT_Module module ) /* SDF_Renderer */ { - SDF_Renderer sdf_render = SDF_RENDERER( render ); + SDF_Renderer sdf_render = SDF_RENDERER( module ); sdf_render->spread = DEFAULT_SPREAD; @@ -236,9 +236,9 @@ static void - ft_sdf_done( FT_Renderer render ) + ft_sdf_done( FT_Module module ) { - FT_UNUSED( render ); + FT_UNUSED( module ); } @@ -300,7 +300,7 @@ /* nothing to render */ if ( !bitmap->rows || !bitmap->pitch ) - return FT_Err_Ok; + goto Exit; /* the padding will simply be equal to the `spread' */ x_pad = sdf_module->spread; @@ -508,6 +508,10 @@ goto Exit; } + /* nothing to render */ + if ( !bitmap->rows || !bitmap->pitch ) + goto Exit; + /* Do not generate SDF if the bitmap is not owned by the */ /* glyph: it might be that the source buffer is already freed. */ if ( !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) @@ -519,10 +523,6 @@ goto Exit; } - /* nothing to render */ - if ( !bitmap->rows || !bitmap->pitch ) - return FT_Err_Ok; - FT_Bitmap_New( &target ); /* padding will simply be equal to `spread` */ @@ -557,15 +557,14 @@ { /* the glyph is successfully converted to a SDF */ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { FT_FREE( bitmap->buffer ); - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - slot->bitmap = target; - slot->bitmap_top += y_pad; - slot->bitmap_left -= x_pad; - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + slot->bitmap = target; + slot->bitmap_top += y_pad; + slot->bitmap_left -= x_pad; + + if ( target.buffer ) + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; } else if ( target.buffer ) FT_FREE( target.buffer ); diff --git a/thirdparty/freetype/src/sfnt/pngshim.c b/thirdparty/freetype/src/sfnt/pngshim.c index 423b07b02a..33712162e0 100644 --- a/thirdparty/freetype/src/sfnt/pngshim.c +++ b/thirdparty/freetype/src/sfnt/pngshim.c @@ -406,10 +406,7 @@ switch ( color_type ) { - default: - /* Shouldn't happen, but ... */ - FALL_THROUGH; - + default: /* Shouldn't happen, but ... */ case PNG_COLOR_TYPE_RGB_ALPHA: png_set_read_user_transform_fn( png, premultiply_data ); break; @@ -457,7 +454,7 @@ #else /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */ /* ANSI C doesn't like empty source files */ - typedef int _pngshim_dummy; + typedef int pngshim_dummy_; #endif /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */ diff --git a/thirdparty/freetype/src/sfnt/sfdriver.c b/thirdparty/freetype/src/sfnt/sfdriver.c index 762883db54..0925940b03 100644 --- a/thirdparty/freetype/src/sfnt/sfdriver.c +++ b/thirdparty/freetype/src/sfnt/sfdriver.c @@ -79,41 +79,57 @@ * */ - static void* - get_sfnt_table( TT_Face face, + FT_CALLBACK_DEF( FT_Error ) + sfnt_load_table( FT_Face face, /* TT_Face */ + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) + { + TT_Face ttface = (TT_Face)face; + + + return tt_face_load_any( ttface, tag, offset, buffer, length ); + } + + + FT_CALLBACK_DEF( void* ) + get_sfnt_table( FT_Face face, /* TT_Face */ FT_Sfnt_Tag tag ) { + TT_Face ttface = (TT_Face)face; + void* table; switch ( tag ) { case FT_SFNT_HEAD: - table = &face->header; + table = &ttface->header; break; case FT_SFNT_HHEA: - table = &face->horizontal; + table = &ttface->horizontal; break; case FT_SFNT_VHEA: - table = face->vertical_info ? &face->vertical : NULL; + table = ttface->vertical_info ? &ttface->vertical : NULL; break; case FT_SFNT_OS2: - table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2; + table = ( ttface->os2.version == 0xFFFFU ) ? NULL : &ttface->os2; break; case FT_SFNT_POST: - table = &face->postscript; + table = &ttface->postscript; break; case FT_SFNT_MAXP: - table = &face->max_profile; + table = &ttface->max_profile; break; case FT_SFNT_PCLT: - table = face->pclt.Version ? &face->pclt : NULL; + table = ttface->pclt.Version ? &ttface->pclt : NULL; break; default: @@ -124,26 +140,29 @@ } - static FT_Error - sfnt_table_info( TT_Face face, + FT_CALLBACK_DEF( FT_Error ) + sfnt_table_info( FT_Face face, /* TT_Face */ FT_UInt idx, FT_ULong *tag, FT_ULong *offset, FT_ULong *length ) { + TT_Face ttface = (TT_Face)face; + + if ( !offset || !length ) return FT_THROW( Invalid_Argument ); if ( !tag ) - *length = face->num_tables; + *length = ttface->num_tables; else { - if ( idx >= face->num_tables ) + if ( idx >= ttface->num_tables ) return FT_THROW( Table_Missing ); - *tag = face->dir_tables[idx].Tag; - *offset = face->dir_tables[idx].Offset; - *length = face->dir_tables[idx].Length; + *tag = ttface->dir_tables[idx].Tag; + *offset = ttface->dir_tables[idx].Offset; + *length = ttface->dir_tables[idx].Length; } return FT_Err_Ok; @@ -153,9 +172,9 @@ FT_DEFINE_SERVICE_SFNT_TABLEREC( sfnt_service_sfnt_table, - (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */ - (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */ - (FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */ + sfnt_load_table, /* FT_SFNT_TableLoadFunc load_table */ + get_sfnt_table, /* FT_SFNT_TableGetFunc get_table */ + sfnt_table_info /* FT_SFNT_TableInfoFunc table_info */ ) @@ -166,7 +185,7 @@ * */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) sfnt_get_glyph_name( FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, @@ -184,7 +203,7 @@ } - static FT_UInt + FT_CALLBACK_DEF( FT_UInt ) sfnt_get_name_index( FT_Face face, const FT_String* glyph_name ) { @@ -221,8 +240,8 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( sfnt_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */ - (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index /* name_index */ + sfnt_get_glyph_name, /* FT_GlyphDict_GetNameFunc get_name */ + sfnt_get_name_index /* FT_GlyphDict_NameIndexFunc name_index */ ) #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -523,15 +542,14 @@ FT_TRACE0(( "get_win_string:" " Character 0x%X invalid in PS name string\n", ((unsigned)p[0])*256 + (unsigned)p[1] )); - break; + continue; } } - if ( !len ) - *r = '\0'; + *r = '\0'; FT_FRAME_EXIT(); - if ( !len ) + if ( r != result ) return result; get_win_string_error: @@ -580,15 +598,14 @@ FT_TRACE0(( "get_apple_string:" " Character `%c' (0x%X) invalid in PS name string\n", *p, *p )); - break; + continue; } } - if ( !len ) - *r = '\0'; + *r = '\0'; FT_FRAME_EXIT(); - if ( !len ) + if ( r != result ) return result; get_apple_string_error: @@ -602,7 +619,7 @@ } - static FT_Bool + FT_CALLBACK_DEF( FT_Bool ) sfnt_get_name_id( TT_Face face, FT_UShort id, FT_Int *win, @@ -819,9 +836,9 @@ if ( !found ) { - /* as a last resort we try the family name; note that this is */ - /* not in the Adobe TechNote, but GX fonts (which predate the */ - /* TechNote) benefit from this behaviour */ + /* according to the 'name' documentation in the OpenType */ + /* specification the font family name is to be used if the */ + /* typographic family name is missing, so let's do that */ found = sfnt_get_name_id( face, TT_NAME_ID_FONT_FAMILY, &win, @@ -853,6 +870,10 @@ { FT_TRACE0(( "sfnt_get_var_ps_name:" " No valid PS name prefix for font instances found\n" )); + /* XXX It probably makes sense to never let this fail */ + /* since an arbitrary prefix should work, too. */ + /* On the other hand, it is very unlikely that */ + /* we ever reach this code at all. */ return NULL; } @@ -1041,47 +1062,49 @@ #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ - static const char* - sfnt_get_ps_name( TT_Face face ) + FT_CALLBACK_DEF( const char* ) + sfnt_get_ps_name( FT_Face face ) /* TT_Face */ { + TT_Face ttface = (TT_Face)face; + FT_Int found, win, apple; const char* result = NULL; - if ( face->postscript_name ) - return face->postscript_name; + if ( ttface->postscript_name ) + return ttface->postscript_name; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( face->blend && - ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) || - FT_IS_VARIATION( FT_FACE( face ) ) ) ) + if ( ttface->blend && + ( FT_IS_NAMED_INSTANCE( face ) || + FT_IS_VARIATION( face ) ) ) { - face->postscript_name = sfnt_get_var_ps_name( face ); - return face->postscript_name; + ttface->postscript_name = sfnt_get_var_ps_name( ttface ); + return ttface->postscript_name; } #endif /* scan the name table to see whether we have a Postscript name here, */ /* either in Macintosh or Windows platform encodings */ - found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple ); + found = sfnt_get_name_id( ttface, TT_NAME_ID_PS_NAME, &win, &apple ); if ( !found ) return NULL; /* prefer Windows entries over Apple */ if ( win != -1 ) - result = get_win_string( face->root.memory, - face->name_table.stream, - face->name_table.names + win, + result = get_win_string( FT_FACE_MEMORY( face ), + ttface->name_table.stream, + ttface->name_table.names + win, sfnt_is_postscript, 1 ); if ( !result && apple != -1 ) - result = get_apple_string( face->root.memory, - face->name_table.stream, - face->name_table.names + apple, + result = get_apple_string( FT_FACE_MEMORY( face ), + ttface->name_table.stream, + ttface->name_table.names + apple, sfnt_is_postscript, 1 ); - face->postscript_name = result; + ttface->postscript_name = result; return result; } @@ -1090,7 +1113,7 @@ FT_DEFINE_SERVICE_PSFONTNAMEREC( sfnt_service_ps_name, - (FT_PsName_GetFunc)sfnt_get_ps_name /* get_ps_font_name */ + sfnt_get_ps_name /* FT_PsName_GetFunc get_ps_font_name */ ) @@ -1100,14 +1123,14 @@ FT_DEFINE_SERVICE_TTCMAPSREC( tt_service_get_cmap_info, - (TT_CMap_Info_GetFunc)tt_get_cmap_info /* get_cmap_info */ + tt_get_cmap_info /* TT_CMap_Info_GetFunc get_cmap_info */ ) #ifdef TT_CONFIG_OPTION_BDF static FT_Error - sfnt_get_charset_id( TT_Face face, + sfnt_get_charset_id( FT_Face face, const char* *acharset_encoding, const char* *acharset_registry ) { @@ -1145,8 +1168,8 @@ FT_DEFINE_SERVICE_BDFRec( sfnt_service_bdf, - (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */ - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop /* get_property */ + sfnt_get_charset_id, /* FT_BDF_GetCharsetIdFunc get_charset_id */ + tt_face_find_bdf_prop /* FT_BDF_GetPropertyFunc get_property */ ) @@ -1337,9 +1360,9 @@ (const void*)&sfnt_interface, /* module specific interface */ - (FT_Module_Constructor)NULL, /* module_init */ - (FT_Module_Destructor) NULL, /* module_done */ - (FT_Module_Requester) sfnt_get_interface /* get_interface */ + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ + sfnt_get_interface /* FT_Module_Requester get_interface */ ) diff --git a/thirdparty/freetype/src/sfnt/sfobjs.c b/thirdparty/freetype/src/sfnt/sfobjs.c index e018934cca..f5d66ef840 100644 --- a/thirdparty/freetype/src/sfnt/sfobjs.c +++ b/thirdparty/freetype/src/sfnt/sfobjs.c @@ -534,17 +534,23 @@ 0 ); } - if ( !face->var ) + if ( !face->tt_var ) { /* we want the metrics variations interface */ /* from the `truetype' module only */ FT_Module tt_module = FT_Get_Module( library, "truetype" ); - face->var = ft_module_get_service( tt_module, - FT_SERVICE_ID_METRICS_VARIATIONS, - 0 ); + face->tt_var = ft_module_get_service( tt_module, + FT_SERVICE_ID_METRICS_VARIATIONS, + 0 ); } + + if ( !face->face_var ) + face->face_var = ft_module_get_service( + &face->root.driver->root, + FT_SERVICE_ID_METRICS_VARIATIONS, + 0 ); #endif FT_TRACE2(( "SFNT driver\n" )); @@ -692,6 +698,9 @@ instance_offset += instance_size; } + /* named instance indices start with value 1 */ + face->var_default_named_instance = i + 1; + if ( i == num_instances ) { /* no default instance in named instance table; */ @@ -1054,6 +1063,16 @@ GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); } +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + { + FT_Memory memory = face->root.memory; + + + if ( FT_STRDUP( face->non_var_style_name, face->root.style_name ) ) + goto Exit; + } +#endif + /* now set up root fields */ { FT_Face root = &face->root; @@ -1221,7 +1240,7 @@ if ( count > 0 ) { - FT_Memory memory = face->root.stream->memory; + FT_Memory memory = face->root.memory; FT_UShort em_size = face->header.Units_Per_EM; FT_Short avgwidth = face->os2.xAvgCharWidth; FT_Size_Metrics metrics; @@ -1500,6 +1519,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_FREE( face->var_postscript_prefix ); + FT_FREE( face->non_var_style_name ); #endif /* freeing glyph color palette data */ diff --git a/thirdparty/freetype/src/sfnt/sfwoff.c b/thirdparty/freetype/src/sfnt/sfwoff.c index 9559bf3421..7c0ce2205e 100644 --- a/thirdparty/freetype/src/sfnt/sfwoff.c +++ b/thirdparty/freetype/src/sfnt/sfwoff.c @@ -426,7 +426,7 @@ #else /* !FT_CONFIG_OPTION_USE_ZLIB */ /* ANSI C doesn't like empty source files */ - typedef int _sfwoff_dummy; + typedef int sfwoff_dummy_; #endif /* !FT_CONFIG_OPTION_USE_ZLIB */ diff --git a/thirdparty/freetype/src/sfnt/sfwoff2.c b/thirdparty/freetype/src/sfnt/sfwoff2.c index 7a01977f86..49ad5cc811 100644 --- a/thirdparty/freetype/src/sfnt/sfwoff2.c +++ b/thirdparty/freetype/src/sfnt/sfwoff2.c @@ -2378,7 +2378,7 @@ #else /* !FT_CONFIG_OPTION_USE_BROTLI */ /* ANSI C doesn't like empty source files */ - typedef int _sfwoff2_dummy; + typedef int sfwoff2_dummy_; #endif /* !FT_CONFIG_OPTION_USE_BROTLI */ diff --git a/thirdparty/freetype/src/sfnt/ttbdf.c b/thirdparty/freetype/src/sfnt/ttbdf.c index 118f475e7f..536fa7467e 100644 --- a/thirdparty/freetype/src/sfnt/ttbdf.c +++ b/thirdparty/freetype/src/sfnt/ttbdf.c @@ -136,13 +136,14 @@ FT_LOCAL_DEF( FT_Error ) - tt_face_find_bdf_prop( TT_Face face, + tt_face_find_bdf_prop( FT_Face face, /* TT_Face */ const char* property_name, BDF_PropertyRec *aprop ) { - TT_BDF bdf = &face->bdf; - FT_Size size = FT_FACE( face )->size; - FT_Error error = FT_Err_Ok; + TT_Face ttface = (TT_Face)face; + TT_BDF bdf = &ttface->bdf; + FT_Size size = FT_FACE_SIZE( face ); + FT_Error error = FT_Err_Ok; FT_Byte* p; FT_UInt count; FT_Byte* strike; @@ -153,7 +154,7 @@ if ( bdf->loaded == 0 ) { - error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); + error = tt_face_load_bdf_props( ttface, FT_FACE_STREAM( face ) ); if ( error ) goto Exit; } @@ -248,7 +249,7 @@ #else /* !TT_CONFIG_OPTION_BDF */ /* ANSI C doesn't like empty source files */ - typedef int _tt_bdf_dummy; + typedef int tt_bdf_dummy_; #endif /* !TT_CONFIG_OPTION_BDF */ diff --git a/thirdparty/freetype/src/sfnt/ttbdf.h b/thirdparty/freetype/src/sfnt/ttbdf.h index 595aeb76c2..0d7a0acecc 100644 --- a/thirdparty/freetype/src/sfnt/ttbdf.h +++ b/thirdparty/freetype/src/sfnt/ttbdf.h @@ -34,7 +34,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - tt_face_find_bdf_prop( TT_Face face, + tt_face_find_bdf_prop( FT_Face face, const char* property_name, BDF_PropertyRec *aprop ); diff --git a/thirdparty/freetype/src/sfnt/ttcmap.c b/thirdparty/freetype/src/sfnt/ttcmap.c index 820cd08e6d..9ba25dcbc1 100644 --- a/thirdparty/freetype/src/sfnt/ttcmap.c +++ b/thirdparty/freetype/src/sfnt/ttcmap.c @@ -59,10 +59,14 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap_init( TT_CMap cmap, - FT_Byte* table ) + tt_cmap_init( FT_CMap cmap, /* TT_CMap */ + void* table_ ) { - cmap->data = table; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = (FT_Byte*)table_; + + + ttcmap->data = table; return FT_Err_Ok; } @@ -128,21 +132,23 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap0_char_index( TT_CMap cmap, + tt_cmap0_char_index( FT_CMap cmap, /* TT_CMap */ FT_UInt32 char_code ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; return char_code < 256 ? table[6 + char_code] : 0; } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap0_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap0_char_next( FT_CMap cmap, /* TT_CMap */ FT_UInt32 *pchar_code ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; FT_UInt32 charcode = *pchar_code; FT_UInt32 result = 0; FT_UInt gindex = 0; @@ -165,10 +171,11 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap0_get_info( TT_CMap cmap, + tt_cmap0_get_info( FT_CharMap cmap, /* TT_CMap */ TT_CMapInfo *cmap_info ) { - FT_Byte* p = cmap->data + 4; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = ttcmap->data + 4; cmap_info->format = 0; @@ -453,10 +460,11 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap2_char_index( TT_CMap cmap, + tt_cmap2_char_index( FT_CMap cmap, /* TT_CMap */ FT_UInt32 char_code ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; FT_UInt result = 0; FT_Byte* subheader; @@ -491,11 +499,12 @@ } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap2_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap2_char_next( FT_CMap cmap, /* TT_CMap */ FT_UInt32 *pcharcode ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; FT_UInt gindex = 0; FT_UInt32 result = 0; FT_UInt32 charcode = *pcharcode + 1; @@ -579,10 +588,11 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap2_get_info( TT_CMap cmap, + tt_cmap2_get_info( FT_CharMap cmap, /* TT_CMap */ TT_CMapInfo *cmap_info ) { - FT_Byte* p = cmap->data + 4; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = ttcmap->data + 4; cmap_info->format = 2; @@ -706,18 +716,20 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap4_init( TT_CMap4 cmap, - FT_Byte* table ) + tt_cmap4_init( FT_CMap cmap, /* TT_CMap4 */ + void* table_ ) { + TT_CMap4 ttcmap = (TT_CMap4)cmap; + FT_Byte* table = (FT_Byte*)table_; FT_Byte* p; - cmap->cmap.data = table; + ttcmap->cmap.data = table; - p = table + 6; - cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; - cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; - cmap->cur_gindex = 0; + p = table + 6; + ttcmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; + ttcmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; + ttcmap->cur_gindex = 0; return FT_Err_Ok; } @@ -755,7 +767,7 @@ cmap->cur_start == 0xFFFFU && cmap->cur_end == 0xFFFFU ) { - TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); FT_Byte* limit = face->cmap_table + face->cmap_size; @@ -788,15 +800,12 @@ static void tt_cmap4_next( TT_CMap4 cmap ) { - TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); FT_Byte* limit = face->cmap_table + face->cmap_size; FT_UInt charcode; - if ( cmap->cur_charcode >= 0xFFFFUL ) - goto Fail; - charcode = (FT_UInt)cmap->cur_charcode + 1; if ( charcode < cmap->cur_start ) @@ -882,7 +891,6 @@ charcode = cmap->cur_start; } - Fail: cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; } @@ -1097,32 +1105,26 @@ FT_UInt32* pcharcode, FT_Bool next ) { - TT_Face face = (TT_Face)cmap->cmap.charmap.face; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); FT_Byte* limit = face->cmap_table + face->cmap_size; FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt i, num_segs; - FT_UInt32 charcode = *pcharcode; + FT_UInt32 charcode = *pcharcode + next; FT_UInt gindex = 0; FT_Byte* p; FT_Byte* q; p = cmap->data + 6; - num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); - - num_segs = num_segs2 >> 1; + num_segs = TT_PEEK_USHORT( p ) >> 1; if ( !num_segs ) return 0; - if ( next ) - charcode++; - - if ( charcode > 0xFFFFU ) - return 0; + num_segs2 = num_segs << 1; /* linear search */ p = cmap->data + 14; /* ends table */ @@ -1232,37 +1234,30 @@ FT_UInt32* pcharcode, FT_Bool next ) { - TT_Face face = (TT_Face)cmap->cmap.charmap.face; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); FT_Byte* limit = face->cmap_table + face->cmap_size; FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt max, min, mid, num_segs; - FT_UInt charcode = (FT_UInt)*pcharcode; + FT_UInt charcode = (FT_UInt)*pcharcode + next; FT_UInt gindex = 0; FT_Byte* p; p = cmap->data + 6; - num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); + num_segs = TT_PEEK_USHORT( p ) >> 1; - if ( !num_segs2 ) + if ( !num_segs ) return 0; - num_segs = num_segs2 >> 1; - - /* make compiler happy */ - mid = num_segs; - end = 0xFFFFU; - - if ( next ) - charcode++; + num_segs2 = num_segs << 1; min = 0; max = num_segs; /* binary search */ - while ( min < max ) + do { mid = ( min + max ) >> 1; p = cmap->data + 14 + mid * 2; @@ -1445,6 +1440,7 @@ break; } } + while ( min < max ); if ( next ) { @@ -1454,12 +1450,8 @@ /* if `charcode' is not in any segment, then `mid' is */ /* the segment nearest to `charcode' */ - if ( charcode > end ) - { - mid++; - if ( mid == num_segs ) - return 0; - } + if ( charcode > end && ++mid == num_segs ) + return 0; if ( tt_cmap4_set_range( cmap4, mid ) ) { @@ -1474,7 +1466,6 @@ cmap4->cur_gindex = gindex; else { - cmap4->cur_charcode = charcode; tt_cmap4_next( cmap4 ); gindex = cmap4->cur_gindex; } @@ -1489,31 +1480,35 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap4_char_index( TT_CMap cmap, + tt_cmap4_char_index( FT_CMap cmap, /* TT_CMap */ FT_UInt32 char_code ) { + TT_CMap ttcmap = (TT_CMap)cmap; + + if ( char_code >= 0x10000UL ) return 0; - if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) - return tt_cmap4_char_map_linear( cmap, &char_code, 0 ); + if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED ) + return tt_cmap4_char_map_linear( ttcmap, &char_code, 0 ); else - return tt_cmap4_char_map_binary( cmap, &char_code, 0 ); + return tt_cmap4_char_map_binary( ttcmap, &char_code, 0 ); } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap4_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap4_char_next( FT_CMap cmap, /* TT_CMap */ FT_UInt32 *pchar_code ) { + TT_CMap ttcmap = (TT_CMap)cmap; FT_UInt gindex; if ( *pchar_code >= 0xFFFFU ) return 0; - if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) - gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 ); + if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED ) + gindex = tt_cmap4_char_map_linear( ttcmap, pchar_code, 1 ); else { TT_CMap4 cmap4 = (TT_CMap4)cmap; @@ -1528,7 +1523,7 @@ *pchar_code = cmap4->cur_charcode; } else - gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 ); + gindex = tt_cmap4_char_map_binary( ttcmap, pchar_code, 1 ); } return gindex; @@ -1536,10 +1531,11 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap4_get_info( TT_CMap cmap, + tt_cmap4_get_info( FT_CharMap cmap, /* TT_CMap */ TT_CMapInfo *cmap_info ) { - FT_Byte* p = cmap->data + 4; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = ttcmap->data + 4; cmap_info->format = 4; @@ -1640,10 +1636,11 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap6_char_index( TT_CMap cmap, + tt_cmap6_char_index( FT_CMap cmap, /* TT_CMap */ FT_UInt32 char_code ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; FT_UInt result = 0; FT_Byte* p = table + 6; FT_UInt start = TT_NEXT_USHORT( p ); @@ -1661,11 +1658,12 @@ } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap6_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap6_char_next( FT_CMap cmap, /* TT_CMap */ FT_UInt32 *pchar_code ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; FT_UInt32 result = 0; FT_UInt32 char_code = *pchar_code + 1; FT_UInt gindex = 0; @@ -1706,10 +1704,11 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap6_get_info( TT_CMap cmap, + tt_cmap6_get_info( FT_CharMap cmap, /* TT_CMap */ TT_CMapInfo *cmap_info ) { - FT_Byte* p = cmap->data + 4; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = ttcmap->data + 4; cmap_info->format = 6; @@ -1900,10 +1899,11 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap8_char_index( TT_CMap cmap, + tt_cmap8_char_index( FT_CMap cmap, /* TT_CMap */ FT_UInt32 char_code ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; FT_UInt result = 0; FT_Byte* p = table + 8204; FT_UInt32 num_groups = TT_NEXT_ULONG( p ); @@ -1932,15 +1932,16 @@ } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap8_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap8_char_next( FT_CMap cmap, /* TT_CMap */ FT_UInt32 *pchar_code ) { - FT_Face face = cmap->cmap.charmap.face; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Face face = FT_CMAP_FACE( cmap ); FT_UInt32 result = 0; FT_UInt32 char_code; FT_UInt gindex = 0; - FT_Byte* table = cmap->data; + FT_Byte* table = ttcmap->data; FT_Byte* p = table + 8204; FT_UInt32 num_groups = TT_NEXT_ULONG( p ); FT_UInt32 start, end, start_id; @@ -2000,10 +2001,11 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap8_get_info( TT_CMap cmap, + tt_cmap8_get_info( FT_CharMap cmap, /* TT_CMap */ TT_CMapInfo *cmap_info ) { - FT_Byte* p = cmap->data + 8; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = ttcmap->data + 8; cmap_info->format = 8; @@ -2104,10 +2106,11 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap10_char_index( TT_CMap cmap, + tt_cmap10_char_index( FT_CMap cmap, /* TT_CMap */ FT_UInt32 char_code ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; FT_UInt result = 0; FT_Byte* p = table + 12; FT_UInt32 start = TT_NEXT_ULONG( p ); @@ -2130,11 +2133,12 @@ } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap10_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap10_char_next( FT_CMap cmap, /* TT_CMap */ FT_UInt32 *pchar_code ) { - FT_Byte* table = cmap->data; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* table = ttcmap->data; FT_UInt32 char_code; FT_UInt gindex = 0; FT_Byte* p = table + 12; @@ -2172,10 +2176,11 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap10_get_info( TT_CMap cmap, + tt_cmap10_get_info( FT_CharMap cmap, /* TT_CMap */ TT_CMapInfo *cmap_info ) { - FT_Byte* p = cmap->data + 8; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = ttcmap->data + 8; cmap_info->format = 10; @@ -2253,15 +2258,19 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap12_init( TT_CMap12 cmap, - FT_Byte* table ) + tt_cmap12_init( FT_CMap cmap, /* TT_CMap12 */ + void* table_ ) { - cmap->cmap.data = table; + TT_CMap12 ttcmap = (TT_CMap12)cmap; + FT_Byte* table = (FT_Byte*)table_; + - table += 12; - cmap->num_groups = FT_PEEK_ULONG( table ); + ttcmap->cmap.data = table; - cmap->valid = 0; + table += 12; + ttcmap->num_groups = FT_PEEK_ULONG( table ); + + ttcmap->valid = 0; return FT_Err_Ok; } @@ -2331,23 +2340,21 @@ /* cmap->cur_group should be set up properly by caller */ /* */ static void - tt_cmap12_next( TT_CMap12 cmap ) + tt_cmap12_next( FT_CMap cmap ) /* TT_CMap12 */ { - FT_Face face = cmap->cmap.cmap.charmap.face; - FT_Byte* p; - FT_ULong start, end, start_id, char_code; - FT_ULong n; - FT_UInt gindex; - + TT_CMap12 ttcmap = (TT_CMap12)cmap; + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Byte* p; + FT_ULong start, end, start_id, char_code; + FT_ULong n; + FT_UInt gindex; - if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) - goto Fail; - char_code = cmap->cur_charcode + 1; + char_code = ttcmap->cur_charcode + 1; - for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ ) { - p = cmap->cmap.data + 16 + 12 * n; + p = ttcmap->cmap.data + 16 + 12 * n; start = TT_NEXT_ULONG( p ); end = TT_NEXT_ULONG( p ); start_id = TT_PEEK_ULONG( p ); @@ -2379,16 +2386,16 @@ if ( gindex >= (FT_UInt)face->num_glyphs ) continue; - cmap->cur_charcode = char_code; - cmap->cur_gindex = gindex; - cmap->cur_group = n; + ttcmap->cur_charcode = char_code; + ttcmap->cur_gindex = gindex; + ttcmap->cur_group = n; return; } } Fail: - cmap->valid = 0; + ttcmap->valid = 0; } @@ -2400,7 +2407,7 @@ FT_UInt gindex = 0; FT_Byte* p = cmap->data + 12; FT_UInt32 num_groups = TT_PEEK_ULONG( p ); - FT_UInt32 char_code = *pchar_code; + FT_UInt32 char_code = *pchar_code + next; FT_UInt32 start, end, start_id; FT_UInt32 max, min, mid; @@ -2408,23 +2415,11 @@ if ( !num_groups ) return 0; - /* make compiler happy */ - mid = num_groups; - end = 0xFFFFFFFFUL; - - if ( next ) - { - if ( char_code >= 0xFFFFFFFFUL ) - return 0; - - char_code++; - } - min = 0; max = num_groups; /* binary search */ - while ( min < max ) + do { mid = ( min + max ) >> 1; p = cmap->data + 16 + 12 * mid; @@ -2448,22 +2443,19 @@ break; } } + while ( min < max ); if ( next ) { - FT_Face face = cmap->cmap.charmap.face; + FT_Face face = FT_CMAP_FACE( cmap ); TT_CMap12 cmap12 = (TT_CMap12)cmap; /* if `char_code' is not in any group, then `mid' is */ /* the group nearest to `char_code' */ - if ( char_code > end ) - { - mid++; - if ( mid == num_groups ) - return 0; - } + if ( char_code > end && ++mid == num_groups ) + return 0; cmap12->valid = 1; cmap12->cur_charcode = char_code; @@ -2474,7 +2466,7 @@ if ( !gindex ) { - tt_cmap12_next( cmap12 ); + tt_cmap12_next( FT_CMAP( cmap12 ) ); if ( cmap12->valid ) gindex = cmap12->cur_gindex; @@ -2490,25 +2482,28 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap12_char_index( TT_CMap cmap, + tt_cmap12_char_index( FT_CMap cmap, /* TT_CMap */ FT_UInt32 char_code ) { - return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); + return tt_cmap12_char_map_binary( (TT_CMap)cmap, &char_code, 0 ); } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap12_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap12_char_next( FT_CMap cmap, /* TT_CMap12 */ FT_UInt32 *pchar_code ) { TT_CMap12 cmap12 = (TT_CMap12)cmap; FT_UInt gindex; + if ( *pchar_code >= 0xFFFFFFFFUL ) + return 0; + /* no need to search */ if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) { - tt_cmap12_next( cmap12 ); + tt_cmap12_next( FT_CMAP( cmap12 ) ); if ( cmap12->valid ) { gindex = cmap12->cur_gindex; @@ -2518,17 +2513,18 @@ gindex = 0; } else - gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); + gindex = tt_cmap12_char_map_binary( (TT_CMap)cmap, pchar_code, 1 ); return gindex; } FT_CALLBACK_DEF( FT_Error ) - tt_cmap12_get_info( TT_CMap cmap, + tt_cmap12_get_info( FT_CharMap cmap, /* TT_CMap */ TT_CMapInfo *cmap_info ) { - FT_Byte* p = cmap->data + 8; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = ttcmap->data + 8; cmap_info->format = 12; @@ -2606,15 +2602,19 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap13_init( TT_CMap13 cmap, - FT_Byte* table ) + tt_cmap13_init( FT_CMap cmap, /* TT_CMap13 */ + void* table_ ) { - cmap->cmap.data = table; + TT_CMap13 ttcmap = (TT_CMap13)cmap; + FT_Byte* table = (FT_Byte*)table_; + + + ttcmap->cmap.data = table; - table += 12; - cmap->num_groups = FT_PEEK_ULONG( table ); + table += 12; + ttcmap->num_groups = FT_PEEK_ULONG( table ); - cmap->valid = 0; + ttcmap->valid = 0; return FT_Err_Ok; } @@ -2679,23 +2679,21 @@ /* cmap->cur_group should be set up properly by caller */ /* */ static void - tt_cmap13_next( TT_CMap13 cmap ) + tt_cmap13_next( FT_CMap cmap ) /* TT_CMap13 */ { - FT_Face face = cmap->cmap.cmap.charmap.face; - FT_Byte* p; - FT_ULong start, end, glyph_id, char_code; - FT_ULong n; - FT_UInt gindex; - + TT_CMap13 ttcmap = (TT_CMap13)cmap; + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Byte* p; + FT_ULong start, end, glyph_id, char_code; + FT_ULong n; + FT_UInt gindex; - if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) - goto Fail; - char_code = cmap->cur_charcode + 1; + char_code = ttcmap->cur_charcode + 1; - for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ ) { - p = cmap->cmap.data + 16 + 12 * n; + p = ttcmap->cmap.data + 16 + 12 * n; start = TT_NEXT_ULONG( p ); end = TT_NEXT_ULONG( p ); glyph_id = TT_PEEK_ULONG( p ); @@ -2709,17 +2707,16 @@ if ( gindex && gindex < (FT_UInt)face->num_glyphs ) { - cmap->cur_charcode = char_code; - cmap->cur_gindex = gindex; - cmap->cur_group = n; + ttcmap->cur_charcode = char_code; + ttcmap->cur_gindex = gindex; + ttcmap->cur_group = n; return; } } } - Fail: - cmap->valid = 0; + ttcmap->valid = 0; } @@ -2731,7 +2728,7 @@ FT_UInt gindex = 0; FT_Byte* p = cmap->data + 12; FT_UInt32 num_groups = TT_PEEK_ULONG( p ); - FT_UInt32 char_code = *pchar_code; + FT_UInt32 char_code = *pchar_code + next; FT_UInt32 start, end; FT_UInt32 max, min, mid; @@ -2739,23 +2736,11 @@ if ( !num_groups ) return 0; - /* make compiler happy */ - mid = num_groups; - end = 0xFFFFFFFFUL; - - if ( next ) - { - if ( char_code >= 0xFFFFFFFFUL ) - return 0; - - char_code++; - } - min = 0; max = num_groups; /* binary search */ - while ( min < max ) + do { mid = ( min + max ) >> 1; p = cmap->data + 16 + 12 * mid; @@ -2774,6 +2759,7 @@ break; } } + while ( min < max ); if ( next ) { @@ -2784,12 +2770,8 @@ /* if `char_code' is not in any group, then `mid' is */ /* the group nearest to `char_code' */ - if ( char_code > end ) - { - mid++; - if ( mid == num_groups ) - return 0; - } + if ( char_code > end && ++mid == num_groups ) + return 0; cmap13->valid = 1; cmap13->cur_charcode = char_code; @@ -2800,7 +2782,7 @@ if ( !gindex ) { - tt_cmap13_next( cmap13 ); + tt_cmap13_next( FT_CMAP( cmap13 ) ); if ( cmap13->valid ) gindex = cmap13->cur_gindex; @@ -2816,25 +2798,28 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap13_char_index( TT_CMap cmap, + tt_cmap13_char_index( FT_CMap cmap, /* TT_CMap */ FT_UInt32 char_code ) { - return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); + return tt_cmap13_char_map_binary( (TT_CMap)cmap, &char_code, 0 ); } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap13_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap13_char_next( FT_CMap cmap, /* TT_CMap13 */ FT_UInt32 *pchar_code ) { TT_CMap13 cmap13 = (TT_CMap13)cmap; FT_UInt gindex; + if ( *pchar_code >= 0xFFFFFFFFUL ) + return 0; + /* no need to search */ if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) { - tt_cmap13_next( cmap13 ); + tt_cmap13_next( FT_CMAP( cmap13 ) ); if ( cmap13->valid ) { gindex = cmap13->cur_gindex; @@ -2844,17 +2829,18 @@ gindex = 0; } else - gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); + gindex = tt_cmap13_char_map_binary( (TT_CMap)cmap, pchar_code, 1 ); return gindex; } FT_CALLBACK_DEF( FT_Error ) - tt_cmap13_get_info( TT_CMap cmap, + tt_cmap13_get_info( FT_CharMap cmap, /* TT_CMap */ TT_CMapInfo *cmap_info ) { - FT_Byte* p = cmap->data + 8; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = ttcmap->data + 8; cmap_info->format = 13; @@ -2969,14 +2955,15 @@ FT_CALLBACK_DEF( void ) - tt_cmap14_done( TT_CMap14 cmap ) + tt_cmap14_done( FT_CMap cmap ) /* TT_CMap14 */ { - FT_Memory memory = cmap->memory; + TT_CMap14 ttcmap = (TT_CMap14)cmap; + FT_Memory memory = ttcmap->memory; - cmap->max_results = 0; - if ( memory && cmap->results ) - FT_FREE( cmap->results ); + ttcmap->max_results = 0; + if ( memory && ttcmap->results ) + FT_FREE( ttcmap->results ); } @@ -3004,15 +2991,19 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap14_init( TT_CMap14 cmap, - FT_Byte* table ) + tt_cmap14_init( FT_CMap cmap, /* TT_CMap14 */ + void* table_ ) { - cmap->cmap.data = table; + TT_CMap14 ttcmap = (TT_CMap14)cmap; + FT_Byte* table = (FT_Byte*)table_; + - table += 6; - cmap->num_selectors = FT_PEEK_ULONG( table ); - cmap->max_results = 0; - cmap->results = NULL; + ttcmap->cmap.data = table; + + table += 6; + ttcmap->num_selectors = FT_PEEK_ULONG( table ); + ttcmap->max_results = 0; + ttcmap->results = NULL; return FT_Err_Ok; } @@ -3142,7 +3133,7 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap14_char_index( TT_CMap cmap, + tt_cmap14_char_index( FT_CMap cmap, FT_UInt32 char_code ) { FT_UNUSED( cmap ); @@ -3153,8 +3144,8 @@ } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap14_char_next( TT_CMap cmap, + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_next( FT_CMap cmap, FT_UInt32 *pchar_code ) { FT_UNUSED( cmap ); @@ -3166,7 +3157,7 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap14_get_info( TT_CMap cmap, + tt_cmap14_get_info( FT_CharMap cmap, TT_CMapInfo *cmap_info ) { FT_UNUSED( cmap ); @@ -3280,12 +3271,16 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap14_char_var_index( TT_CMap cmap, - TT_CMap ucmap, + tt_cmap14_char_var_index( FT_CMap cmap, /* TT_CMap */ + FT_CMap ucmap, /* TT_CMap */ FT_UInt32 charcode, FT_UInt32 variantSelector ) { - FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + TT_CMap ttcmap = (TT_CMap)cmap; + TT_CMap ttucmap = (TT_CMap)ucmap; + + FT_Byte* p = tt_cmap14_find_variant( ttcmap->data + 6, + variantSelector ); FT_ULong defOff; FT_ULong nondefOff; @@ -3296,16 +3291,16 @@ defOff = TT_NEXT_ULONG( p ); nondefOff = TT_PEEK_ULONG( p ); - if ( defOff != 0 && - tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) ) { /* This is the default variant of this charcode. GID not stored */ /* here; stored in the normal Unicode charmap instead. */ - return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); + return ttucmap->cmap.clazz->char_index( &ttucmap->cmap, charcode ); } if ( nondefOff != 0 ) - return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + return tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff, charcode ); return 0; @@ -3313,11 +3308,13 @@ FT_CALLBACK_DEF( FT_Int ) - tt_cmap14_char_var_isdefault( TT_CMap cmap, + tt_cmap14_char_var_isdefault( FT_CMap cmap, /* TT_CMap */ FT_UInt32 charcode, FT_UInt32 variantSelector ) { - FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte* p = tt_cmap14_find_variant( ttcmap->data + 6, + variantSelector ); FT_ULong defOff; FT_ULong nondefOff; @@ -3328,13 +3325,13 @@ defOff = TT_NEXT_ULONG( p ); nondefOff = TT_NEXT_ULONG( p ); - if ( defOff != 0 && - tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) ) return 1; - if ( nondefOff != 0 && - tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, - charcode ) != 0 ) + if ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff, + charcode ) != 0 ) return 0; return -1; @@ -3342,12 +3339,13 @@ FT_CALLBACK_DEF( FT_UInt32* ) - tt_cmap14_variants( TT_CMap cmap, + tt_cmap14_variants( FT_CMap cmap, /* TT_CMap14 */ FT_Memory memory ) { + TT_CMap ttcmap = (TT_CMap)cmap; TT_CMap14 cmap14 = (TT_CMap14)cmap; FT_UInt32 count = cmap14->num_selectors; - FT_Byte* p = cmap->data + 10; + FT_Byte* p = ttcmap->data + 10; FT_UInt32* result; FT_UInt32 i; @@ -3368,13 +3366,14 @@ FT_CALLBACK_DEF( FT_UInt32 * ) - tt_cmap14_char_variants( TT_CMap cmap, + tt_cmap14_char_variants( FT_CMap cmap, /* TT_CMap14 */ FT_Memory memory, FT_UInt32 charCode ) { - TT_CMap14 cmap14 = (TT_CMap14) cmap; + TT_CMap ttcmap = (TT_CMap)cmap; + TT_CMap14 cmap14 = (TT_CMap14)cmap; FT_UInt32 count = cmap14->num_selectors; - FT_Byte* p = cmap->data + 10; + FT_Byte* p = ttcmap->data + 10; FT_UInt32* q; @@ -3388,12 +3387,12 @@ FT_ULong nondefOff = TT_NEXT_ULONG( p ); - if ( ( defOff != 0 && - tt_cmap14_char_map_def_binary( cmap->data + defOff, - charCode ) ) || - ( nondefOff != 0 && - tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, - charCode ) != 0 ) ) + if ( ( defOff != 0 && + tt_cmap14_char_map_def_binary( ttcmap->data + defOff, + charCode ) ) || + ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff, + charCode ) != 0 ) ) { q[0] = varSel; q++; @@ -3489,15 +3488,16 @@ FT_CALLBACK_DEF( FT_UInt32 * ) - tt_cmap14_variant_chars( TT_CMap cmap, + tt_cmap14_variant_chars( FT_CMap cmap, /* TT_CMap */ FT_Memory memory, FT_UInt32 variantSelector ) { - FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, - variantSelector ); - FT_Int i; - FT_ULong defOff; - FT_ULong nondefOff; + TT_CMap ttcmap = (TT_CMap)cmap; + FT_Byte *p = tt_cmap14_find_variant( ttcmap->data + 6, + variantSelector ); + FT_Int i; + FT_ULong defOff; + FT_ULong nondefOff; if ( !p ) @@ -3510,16 +3510,16 @@ return NULL; if ( defOff == 0 ) - return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff, memory ); else if ( nondefOff == 0 ) - return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff, memory ); else { /* Both a default and a non-default glyph set? That's probably not */ /* good font design, but the spec allows for it... */ - TT_CMap14 cmap14 = (TT_CMap14) cmap; + TT_CMap14 cmap14 = (TT_CMap14)cmap; FT_UInt32 numRanges; FT_UInt32 numMappings; FT_UInt32 duni; @@ -3531,18 +3531,18 @@ FT_UInt32 *ret; - p = cmap->data + nondefOff; - dp = cmap->data + defOff; + p = ttcmap->data + nondefOff; + dp = ttcmap->data + defOff; numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); dcnt = tt_cmap14_def_char_count( dp ); numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); if ( numMappings == 0 ) - return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff, memory ); if ( dcnt == 0 ) - return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff, memory ); if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) @@ -3664,9 +3664,10 @@ #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES FT_CALLBACK_DEF( const char * ) - tt_get_glyph_name( TT_Face face, + tt_get_glyph_name( void* face_, /* TT_Face */ FT_UInt idx ) { + TT_Face face = (TT_Face)face_; FT_String* PSname = NULL; @@ -3677,12 +3678,13 @@ FT_CALLBACK_DEF( FT_Error ) - tt_cmap_unicode_init( PS_Unicodes unicodes, - FT_Pointer pointer ) + tt_cmap_unicode_init( FT_CMap cmap, /* PS_Unicodes */ + FT_Pointer pointer ) { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; FT_UNUSED( pointer ); @@ -3693,17 +3695,18 @@ return psnames->unicodes_init( memory, unicodes, face->root.num_glyphs, - (PS_GetGlyphNameFunc)&tt_get_glyph_name, + &tt_get_glyph_name, (PS_FreeGlyphNameFunc)NULL, (FT_Pointer)face ); } FT_CALLBACK_DEF( void ) - tt_cmap_unicode_done( PS_Unicodes unicodes ) + tt_cmap_unicode_done( FT_CMap cmap ) /* PS_Unicodes */ { - FT_Face face = FT_CMAP_FACE( unicodes ); - FT_Memory memory = FT_FACE_MEMORY( face ); + PS_Unicodes unicodes = (PS_Unicodes)cmap; + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( unicodes->maps ); @@ -3712,23 +3715,25 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap_unicode_char_index( PS_Unicodes unicodes, - FT_UInt32 char_code ) + tt_cmap_unicode_char_index( FT_CMap cmap, /* PS_Unicodes */ + FT_UInt32 char_code ) { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; return psnames->unicodes_char_index( unicodes, char_code ); } - FT_CALLBACK_DEF( FT_UInt32 ) - tt_cmap_unicode_char_next( PS_Unicodes unicodes, - FT_UInt32 *pchar_code ) + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap_unicode_char_next( FT_CMap cmap, /* PS_Unicodes */ + FT_UInt32 *pchar_code ) { - TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); - FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + PS_Unicodes unicodes = (PS_Unicodes)cmap; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; return psnames->unicodes_char_next( unicodes, pchar_code ); @@ -3883,7 +3888,7 @@ tt_get_cmap_info( FT_CharMap charmap, TT_CMapInfo *cmap_info ) { - FT_CMap cmap = (FT_CMap)charmap; + FT_CMap cmap = FT_CMAP( charmap ); TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; diff --git a/thirdparty/freetype/src/sfnt/ttcolr.c b/thirdparty/freetype/src/sfnt/ttcolr.c index 5d98dcab8f..69ccf0ee7a 100644 --- a/thirdparty/freetype/src/sfnt/ttcolr.c +++ b/thirdparty/freetype/src/sfnt/ttcolr.c @@ -699,7 +699,7 @@ item_deltas ) ) return 0; - apaint->u.solid.color.alpha += item_deltas[0]; + apaint->u.solid.color.alpha += (FT_F2Dot14)item_deltas[0]; } #endif @@ -1646,7 +1646,7 @@ return 0; color_stop->stop_offset += F2DOT14_TO_FIXED( item_deltas[0] ); - color_stop->color.alpha += item_deltas[1]; + color_stop->color.alpha += (FT_F2Dot14)item_deltas[1]; } #else FT_UNUSED( var_index_base ); @@ -1914,7 +1914,7 @@ #else /* !TT_CONFIG_OPTION_COLOR_LAYERS */ /* ANSI C doesn't like empty source files */ - typedef int _tt_colr_dummy; + typedef int tt_colr_dummy_; #endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */ diff --git a/thirdparty/freetype/src/sfnt/ttcpal.c b/thirdparty/freetype/src/sfnt/ttcpal.c index 4279bc0bd1..46ae08596f 100644 --- a/thirdparty/freetype/src/sfnt/ttcpal.c +++ b/thirdparty/freetype/src/sfnt/ttcpal.c @@ -303,7 +303,7 @@ #else /* !TT_CONFIG_OPTION_COLOR_LAYERS */ /* ANSI C doesn't like empty source files */ - typedef int _tt_cpal_dummy; + typedef int tt_cpal_dummy_; #endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */ diff --git a/thirdparty/freetype/src/sfnt/ttload.c b/thirdparty/freetype/src/sfnt/ttload.c index 14f625c824..7b44e9cd2e 100644 --- a/thirdparty/freetype/src/sfnt/ttload.c +++ b/thirdparty/freetype/src/sfnt/ttload.c @@ -504,6 +504,13 @@ FT_FRAME_EXIT(); + if ( !valid_entries ) + { + FT_TRACE2(( "tt_face_load_font_dir: no valid tables found\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + FT_TRACE2(( "table directory loaded\n" )); FT_TRACE2(( "\n" )); diff --git a/thirdparty/freetype/src/sfnt/ttmtx.c b/thirdparty/freetype/src/sfnt/ttmtx.c index 5e53e6dd4a..38ee9ae728 100644 --- a/thirdparty/freetype/src/sfnt/ttmtx.c +++ b/thirdparty/freetype/src/sfnt/ttmtx.c @@ -239,7 +239,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_Service_MetricsVariations var = - (FT_Service_MetricsVariations)face->var; + (FT_Service_MetricsVariations)face->tt_var; #endif diff --git a/thirdparty/freetype/src/sfnt/ttpost.c b/thirdparty/freetype/src/sfnt/ttpost.c index 0e17c6f34a..1dfad4298b 100644 --- a/thirdparty/freetype/src/sfnt/ttpost.c +++ b/thirdparty/freetype/src/sfnt/ttpost.c @@ -156,86 +156,66 @@ static FT_Error - load_format_20( TT_Face face, - FT_Stream stream, - FT_ULong post_len ) + load_format_20( TT_Post_Names names, + FT_Stream stream, + FT_UShort num_glyphs, + FT_ULong post_len ) { FT_Memory memory = stream->memory; FT_Error error; - FT_Int num_glyphs; - FT_UShort num_names; + FT_UShort n; + FT_UShort num_names = 0; FT_UShort* glyph_indices = NULL; - FT_Char** name_strings = NULL; - FT_Byte* strings = NULL; + FT_Byte** name_strings = NULL; + FT_Byte* q; - if ( FT_READ_USHORT( num_glyphs ) ) - goto Exit; - - /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ - /* than the value in the maxp table (cf. cyberbit.ttf). */ - - /* There already exist fonts which have more than 32768 glyph names */ - /* in this table, so the test for this threshold has been dropped. */ - - if ( num_glyphs > face->max_profile.numGlyphs || - (FT_ULong)num_glyphs * 2UL > post_len - 2 ) + if ( (FT_ULong)num_glyphs * 2 > post_len ) { error = FT_THROW( Invalid_File_Format ); goto Exit; } - /* load the indices */ - { - FT_Int n; - - - if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) || - FT_FRAME_ENTER( num_glyphs * 2L ) ) - goto Fail; - - for ( n = 0; n < num_glyphs; n++ ) - glyph_indices[n] = FT_GET_USHORT(); + /* load the indices and note their maximum */ + if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) || + FT_FRAME_ENTER( num_glyphs * 2 ) ) + goto Fail; - FT_FRAME_EXIT(); - } + q = (FT_Byte*)stream->cursor; - /* compute number of names stored in table */ + for ( n = 0; n < num_glyphs; n++ ) { - FT_Int n; + FT_UShort idx = FT_NEXT_USHORT( q ); - num_names = 0; + if ( idx > num_names ) + num_names = idx; - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Int idx; + glyph_indices[n] = idx; + } + FT_FRAME_EXIT(); - idx = glyph_indices[n]; - if ( idx >= 258 ) - { - idx -= 257; - if ( idx > num_names ) - num_names = (FT_UShort)idx; - } - } - } + /* compute number of names stored in the table */ + num_names = num_names > 257 ? num_names - 257 : 0; /* now load the name strings */ if ( num_names ) { - FT_UShort n; FT_ULong p; + FT_Byte* strings; - post_len -= (FT_ULong)num_glyphs * 2UL + 2; + post_len -= (FT_ULong)num_glyphs * 2; + + if ( FT_QALLOC( name_strings, num_names * sizeof ( FT_Byte* ) + + post_len + 1 ) ) + goto Fail; - if ( FT_QALLOC( strings, post_len + 1 ) || - FT_STREAM_READ( strings, post_len ) || - FT_QNEW_ARRAY( name_strings, num_names ) ) + strings = (FT_Byte*)( name_strings + num_names ); + if ( FT_STREAM_READ( strings, post_len ) ) goto Fail; /* convert from Pascal- to C-strings and set pointers */ @@ -251,7 +231,7 @@ } strings[p] = 0; - name_strings[n] = (FT_Char*)strings + p + 1; + name_strings[n] = strings + p + 1; p += len + 1; } strings[post_len] = 0; @@ -259,40 +239,24 @@ /* deal with missing or insufficient string data */ if ( n < num_names ) { - if ( post_len == 0 ) - { - /* fake empty string */ - if ( FT_QREALLOC( strings, 1, 2 ) ) - goto Fail; - - post_len = 1; - strings[post_len] = 0; - } + FT_TRACE4(( "load_format_20: %hu PostScript names are truncated\n", + num_names - n )); - FT_ERROR(( "load_format_20:" - " all entries in post table are already parsed," - " using NULL names for gid %d - %d\n", - n, num_names - 1 )); for ( ; n < num_names; n++ ) - name_strings[n] = (FT_Char*)strings + post_len; + name_strings[n] = strings + post_len; } } /* all right, set table fields and exit successfully */ - { - TT_Post_20 table = &face->postscript_names.names.format_20; - + names->num_glyphs = num_glyphs; + names->num_names = num_names; + names->glyph_indices = glyph_indices; + names->glyph_names = name_strings; - table->num_glyphs = (FT_UShort)num_glyphs; - table->num_names = (FT_UShort)num_names; - table->glyph_indices = glyph_indices; - table->glyph_names = name_strings; - } return FT_Err_Ok; Fail: FT_FREE( name_strings ); - FT_FREE( strings ); FT_FREE( glyph_indices ); Exit: @@ -301,66 +265,55 @@ static FT_Error - load_format_25( TT_Face face, - FT_Stream stream, - FT_ULong post_len ) + load_format_25( TT_Post_Names names, + FT_Stream stream, + FT_UShort num_glyphs, + FT_ULong post_len ) { FT_Memory memory = stream->memory; FT_Error error; - FT_Int num_glyphs; - FT_Char* offset_table = NULL; - - FT_UNUSED( post_len ); + FT_UShort n; + FT_UShort* glyph_indices = NULL; + FT_Byte* q; - if ( FT_READ_USHORT( num_glyphs ) ) - goto Exit; - - /* check the number of glyphs */ - if ( num_glyphs > face->max_profile.numGlyphs || - num_glyphs > 258 || - num_glyphs < 1 ) + /* check the number of glyphs, including the theoretical limit */ + if ( num_glyphs > post_len || + num_glyphs > 258 + 128 ) { error = FT_THROW( Invalid_File_Format ); goto Exit; } - if ( FT_QNEW_ARRAY( offset_table, num_glyphs ) || - FT_STREAM_READ( offset_table, num_glyphs ) ) + /* load the indices and check their Mac range */ + if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) || + FT_FRAME_ENTER( num_glyphs ) ) goto Fail; - /* now check the offset table */ - { - FT_Int n; + q = (FT_Byte*)stream->cursor; + for ( n = 0; n < num_glyphs; n++ ) + { + FT_Int idx = n + FT_NEXT_CHAR( q ); - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Long idx = (FT_Long)n + offset_table[n]; + if ( idx < 0 || idx > 257 ) + idx = 0; - if ( idx < 0 || idx > num_glyphs ) - { - error = FT_THROW( Invalid_File_Format ); - goto Fail; - } - } + glyph_indices[n] = (FT_UShort)idx; } - /* OK, set table fields and exit successfully */ - { - TT_Post_25 table = &face->postscript_names.names.format_25; - + FT_FRAME_EXIT(); - table->num_glyphs = (FT_UShort)num_glyphs; - table->offsets = offset_table; - } + /* OK, set table fields and exit successfully */ + names->num_glyphs = num_glyphs; + names->glyph_indices = glyph_indices; return FT_Err_Ok; Fail: - FT_FREE( offset_table ); + FT_FREE( glyph_indices ); Exit: return error; @@ -370,37 +323,37 @@ static FT_Error load_post_names( TT_Face face ) { - FT_Stream stream; - FT_Error error; - FT_Fixed format; + FT_Error error = FT_Err_Ok; + FT_Stream stream = face->root.stream; + FT_Fixed format = face->postscript.FormatType; FT_ULong post_len; + FT_UShort num_glyphs; - /* get a stream for the face's resource */ - stream = face->root.stream; - /* seek to the beginning of the PS names table */ error = face->goto_table( face, TTAG_post, stream, &post_len ); if ( error ) goto Exit; - format = face->postscript.FormatType; - - /* go to beginning of subtable */ - if ( FT_STREAM_SKIP( 32 ) ) + /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ + /* than the value in the maxp table (cf. cyberbit.ttf). */ + if ( post_len < 34 || + FT_STREAM_SKIP( 32 ) || + FT_READ_USHORT( num_glyphs ) || + num_glyphs > face->max_profile.numGlyphs || + num_glyphs == 0 ) goto Exit; - /* now read postscript table */ - if ( format == 0x00020000L && post_len >= 34 ) - error = load_format_20( face, stream, post_len - 32 ); - else if ( format == 0x00025000L && post_len >= 34 ) - error = load_format_25( face, stream, post_len - 32 ); - else - error = FT_THROW( Invalid_File_Format ); - - face->postscript_names.loaded = 1; + /* now read postscript names data */ + if ( format == 0x00020000L ) + error = load_format_20( &face->postscript_names, stream, + num_glyphs, post_len - 34 ); + else if ( format == 0x00025000L ) + error = load_format_25( &face->postscript_names, stream, + num_glyphs, post_len - 34 ); Exit: + face->postscript_names.loaded = 1; /* even if failed */ return error; } @@ -410,39 +363,20 @@ { FT_Memory memory = face->root.memory; TT_Post_Names names = &face->postscript_names; - FT_Fixed format; - if ( names->loaded ) + if ( names->num_glyphs ) { - format = face->postscript.FormatType; - - if ( format == 0x00020000L ) - { - TT_Post_20 table = &names->names.format_20; - - - FT_FREE( table->glyph_indices ); - table->num_glyphs = 0; - - if ( table->num_names ) - { - table->glyph_names[0]--; - FT_FREE( table->glyph_names[0] ); - - FT_FREE( table->glyph_names ); - table->num_names = 0; - } - } - else if ( format == 0x00025000L ) - { - TT_Post_25 table = &names->names.format_25; - + FT_FREE( names->glyph_indices ); + names->num_glyphs = 0; + } - FT_FREE( table->offsets ); - table->num_glyphs = 0; - } + if ( names->num_names ) + { + FT_FREE( names->glyph_names ); + names->num_names = 0; } + names->loaded = 0; } @@ -478,7 +412,6 @@ FT_String** PSname ) { FT_Error error; - TT_Post_Names names; FT_Fixed format; #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -498,8 +431,6 @@ return FT_THROW( Unimplemented_Feature ); #endif - names = &face->postscript_names; - /* `.notdef' by default */ *PSname = MAC_NAME( 0 ); @@ -510,9 +441,10 @@ if ( idx < 258 ) /* paranoid checking */ *PSname = MAC_NAME( idx ); } - else if ( format == 0x00020000L ) + else if ( format == 0x00020000L || + format == 0x00025000L ) { - TT_Post_20 table = &names->names.format_20; + TT_Post_Names names = &face->postscript_names; if ( !names->loaded ) @@ -522,43 +454,29 @@ goto End; } - if ( idx < (FT_UInt)table->num_glyphs ) + if ( idx < (FT_UInt)names->num_glyphs ) { - FT_UShort name_index = table->glyph_indices[idx]; + FT_UShort name_index = names->glyph_indices[idx]; if ( name_index < 258 ) *PSname = MAC_NAME( name_index ); - else - *PSname = (FT_String*)table->glyph_names[name_index - 258]; - } - } - else if ( format == 0x00025000L ) - { - TT_Post_25 table = &names->names.format_25; - - - if ( !names->loaded ) - { - error = load_post_names( face ); - if ( error ) - goto End; + else /* only for version 2.0 */ + *PSname = (FT_String*)names->glyph_names[name_index - 258]; } - - if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */ - *PSname = MAC_NAME( (FT_Int)idx + table->offsets[idx] ); } /* nothing to do for format == 0x00030000L */ End: + /* post format errors ignored */ return FT_Err_Ok; } #else /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ /* ANSI C doesn't like empty source files */ - typedef int _tt_post_dummy; + typedef int tt_post_dummy_; #endif /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ diff --git a/thirdparty/freetype/src/sfnt/ttsbit.c b/thirdparty/freetype/src/sfnt/ttsbit.c index 3c06955131..03f90a628d 100644 --- a/thirdparty/freetype/src/sfnt/ttsbit.c +++ b/thirdparty/freetype/src/sfnt/ttsbit.c @@ -1677,7 +1677,7 @@ #else /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ /* ANSI C doesn't like empty source files */ - typedef int _tt_sbit_dummy; + typedef int tt_sbit_dummy_; #endif /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ diff --git a/thirdparty/freetype/src/sfnt/ttsvg.c b/thirdparty/freetype/src/sfnt/ttsvg.c index c1bbb66b81..4461d483b0 100644 --- a/thirdparty/freetype/src/sfnt/ttsvg.c +++ b/thirdparty/freetype/src/sfnt/ttsvg.c @@ -405,7 +405,7 @@ #else /* !FT_CONFIG_OPTION_SVG */ /* ANSI C doesn't like empty source files */ - typedef int _tt_svg_dummy; + typedef int tt_svg_dummy_; #endif /* !FT_CONFIG_OPTION_SVG */ diff --git a/thirdparty/freetype/src/sfnt/woff2tags.c b/thirdparty/freetype/src/sfnt/woff2tags.c index 7a0a351f06..eeedd9906b 100644 --- a/thirdparty/freetype/src/sfnt/woff2tags.c +++ b/thirdparty/freetype/src/sfnt/woff2tags.c @@ -111,7 +111,7 @@ #else /* !FT_CONFIG_OPTION_USE_BROTLI */ /* ANSI C doesn't like empty source files */ - typedef int _woff2tags_dummy; + typedef int woff2tags_dummy_; #endif /* !FT_CONFIG_OPTION_USE_BROTLI */ diff --git a/thirdparty/freetype/src/smooth/ftgrays.c b/thirdparty/freetype/src/smooth/ftgrays.c index d9f20eef13..6252df98ae 100644 --- a/thirdparty/freetype/src/smooth/ftgrays.c +++ b/thirdparty/freetype/src/smooth/ftgrays.c @@ -1006,9 +1006,9 @@ typedef ptrdiff_t FT_PtrDist; * * For other cases, using binary splits is actually slightly faster. */ -#if defined( __SSE2__ ) || \ - defined( __x86_64__ ) || \ - defined( _M_AMD64 ) || \ +#if defined( __SSE2__ ) || \ + ( defined( __x86_64__ ) && !defined( __VMS ) ) || \ + defined( _M_AMD64 ) || \ ( defined( _M_IX86_FP ) && _M_IX86_FP >= 2 ) # define FT_SSE2 1 #else @@ -1427,8 +1427,10 @@ typedef ptrdiff_t FT_PtrDist; static int gray_move_to( const FT_Vector* to, - gray_PWorker worker ) + void* worker_ ) /* gray_PWorker */ { + gray_PWorker worker = (gray_PWorker)worker_; + TPos x, y; @@ -1446,8 +1448,11 @@ typedef ptrdiff_t FT_PtrDist; static int gray_line_to( const FT_Vector* to, - gray_PWorker worker ) + void* worker_ ) /* gray_PWorker */ { + gray_PWorker worker = (gray_PWorker)worker_; + + gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) ); return 0; } @@ -1456,8 +1461,11 @@ typedef ptrdiff_t FT_PtrDist; static int gray_conic_to( const FT_Vector* control, const FT_Vector* to, - gray_PWorker worker ) + void* worker_ ) /* gray_PWorker */ { + gray_PWorker worker = (gray_PWorker)worker_; + + gray_render_conic( RAS_VAR_ control, to ); return 0; } @@ -1467,8 +1475,11 @@ typedef ptrdiff_t FT_PtrDist; gray_cubic_to( const FT_Vector* control1, const FT_Vector* control2, const FT_Vector* to, - gray_PWorker worker ) + void* worker_ ) /* gray_PWorker */ { + gray_PWorker worker = (gray_PWorker)worker_; + + gray_render_cubic( RAS_VAR_ control1, control2, to ); return 0; } @@ -1666,6 +1677,8 @@ typedef ptrdiff_t FT_PtrDist; int n; /* index of contour in outline */ int first; /* index of first point in contour */ + int last; /* index of last point in contour */ + char tag; /* current point's state */ int shift; @@ -1680,18 +1693,17 @@ typedef ptrdiff_t FT_PtrDist; shift = func_interface->shift; delta = func_interface->delta; - first = 0; + last = -1; for ( n = 0; n < outline->n_contours; n++ ) { - int last; /* index of last point in contour */ - - - FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + FT_TRACE5(( "FT_Outline_Decompose: Contour %d\n", n )); + first = last + 1; last = outline->contours[n]; - if ( last < 0 ) + if ( last < first ) goto Invalid_Outline; + limit = outline->points + last; v_start = outline->points[first]; @@ -1874,11 +1886,9 @@ typedef ptrdiff_t FT_PtrDist; v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->line_to( &v_start, user ); - Close: + Close: if ( error ) goto Exit; - - first = last + 1; } FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); @@ -2156,9 +2166,12 @@ typedef ptrdiff_t FT_PtrDist; #else /* !STANDALONE_ */ static int - gray_raster_new( FT_Memory memory, - gray_PRaster* araster ) + gray_raster_new( void* memory_, + FT_Raster* araster_ ) { + FT_Memory memory = (FT_Memory)memory_; + gray_PRaster* araster = (gray_PRaster*)araster_; + FT_Error error; gray_PRaster raster = NULL; diff --git a/thirdparty/freetype/src/smooth/ftsmooth.c b/thirdparty/freetype/src/smooth/ftsmooth.c index cdbc78c3e5..9b0e8886cb 100644 --- a/thirdparty/freetype/src/smooth/ftsmooth.c +++ b/thirdparty/freetype/src/smooth/ftsmooth.c @@ -87,8 +87,10 @@ /* initialize renderer -- init its raster */ static FT_Error - ft_smooth_init( FT_Renderer render ) + ft_smooth_init( FT_Module module ) /* FT_Renderer */ { + FT_Renderer render = (FT_Renderer)module; + FT_Vector* sub = render->root.library->lcd_geometry; @@ -111,8 +113,10 @@ ft_smooth_lcd_spans( int y, int count, const FT_Span* spans, - TOrigin* target ) + void* target_ ) /* TOrigin* */ { + TOrigin* target = (TOrigin*)target_; + unsigned char* dst_line = target->origin - y * target->pitch; unsigned char* dst; unsigned short w; @@ -141,7 +145,7 @@ /* Set up direct rendering to record them on each third byte. */ params.source = outline; params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT; - params.gray_spans = (FT_SpanFunc)ft_smooth_lcd_spans; + params.gray_spans = ft_smooth_lcd_spans; params.user = ⌖ params.clip_box.xMin = 0; @@ -256,8 +260,11 @@ /* initialize renderer -- init its raster */ static FT_Error - ft_smooth_init( FT_Renderer render ) + ft_smooth_init( FT_Module module ) /* FT_Renderer */ { + FT_Renderer render = (FT_Renderer)module; + + /* set up default LCD filtering */ FT_Library_SetLcdFilter( render->root.library, FT_LCD_FILTER_DEFAULT ); @@ -340,8 +347,11 @@ ft_smooth_overlap_spans( int y, int count, const FT_Span* spans, - TOrigin* target ) + void* target_ ) { + TOrigin* target = (TOrigin*)target_; + + unsigned char* dst = target->origin - ( y / SCALE ) * target->pitch; unsigned short x; unsigned int cover, sum; @@ -386,7 +396,7 @@ /* Set up direct rendering to average oversampled spans. */ params.source = outline; params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT; - params.gray_spans = (FT_SpanFunc)ft_smooth_overlap_spans; + params.gray_spans = ft_smooth_overlap_spans; params.user = ⌖ params.clip_box.xMin = 0; diff --git a/thirdparty/freetype/src/svg/ftsvg.c b/thirdparty/freetype/src/svg/ftsvg.c index 7edb1a338e..ba237f6380 100644 --- a/thirdparty/freetype/src/svg/ftsvg.c +++ b/thirdparty/freetype/src/svg/ftsvg.c @@ -40,26 +40,31 @@ /* ft_svg_init */ static FT_Error - ft_svg_init( SVG_Renderer svg_module ) + ft_svg_init( FT_Module module ) { + SVG_Renderer render = (SVG_Renderer)module; + FT_Error error = FT_Err_Ok; - svg_module->loaded = FALSE; - svg_module->hooks_set = FALSE; + render->loaded = FALSE; + render->hooks_set = FALSE; return error; } static void - ft_svg_done( SVG_Renderer svg_module ) + ft_svg_done( FT_Module module ) { - if ( svg_module->loaded == TRUE && - svg_module->hooks_set == TRUE ) - svg_module->hooks.free_svg( &svg_module->state ); + SVG_Renderer render = (SVG_Renderer)module; + + + if ( render->loaded == TRUE && + render->hooks_set == TRUE ) + render->hooks.free_svg( &render->state ); - svg_module->loaded = FALSE; + render->loaded = FALSE; } @@ -148,7 +153,7 @@ static const SVG_Interface svg_interface = { - (Preset_Bitmap_Func)ft_svg_preset_slot + ft_svg_preset_slot /* Preset_Bitmap_Func preset_slot */ }; @@ -203,7 +208,7 @@ static FT_Error ft_svg_property_get( FT_Module module, const char* property_name, - const void* value ) + void* value ) { FT_Error error = FT_Err_Ok; SVG_Renderer renderer = (SVG_Renderer)module; @@ -226,8 +231,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( ft_svg_service_properties, - (FT_Properties_SetFunc)ft_svg_property_set, /* set_property */ - (FT_Properties_GetFunc)ft_svg_property_get /* get_property */ + ft_svg_property_set, /* FT_Properties_SetFunc set_property */ + ft_svg_property_get /* FT_Properties_GetFunc get_property */ ) @@ -333,17 +338,17 @@ (const void*)PUT_SVG_MODULE( &svg_interface ), /* module specific interface */ - (FT_Module_Constructor)PUT_SVG_MODULE( ft_svg_init ), /* module_init */ - (FT_Module_Destructor)PUT_SVG_MODULE( ft_svg_done ), /* module_done */ - PUT_SVG_MODULE( ft_svg_get_interface ), /* get_interface */ + PUT_SVG_MODULE( ft_svg_init ), /* FT_Module_Constructor module_init */ + PUT_SVG_MODULE( ft_svg_done ), /* FT_Module_Destructor module_done */ + PUT_SVG_MODULE( ft_svg_get_interface ), /* FT_Module_Requester get_interface */ SVG_GLYPH_FORMAT, - (FT_Renderer_RenderFunc) PUT_SVG_MODULE( ft_svg_render ), /* render_glyph */ - (FT_Renderer_TransformFunc)PUT_SVG_MODULE( ft_svg_transform ), /* transform_glyph */ - NULL, /* get_glyph_cbox */ - NULL, /* set_mode */ - NULL /* raster_class */ + PUT_SVG_MODULE( ft_svg_render ), /* FT_Renderer_RenderFunc render_glyph */ + PUT_SVG_MODULE( ft_svg_transform ), /* FT_Renderer_TransformFunc transform_glyph */ + NULL, /* FT_Renderer_GetCBoxFunc get_glyph_cbox */ + NULL, /* FT_Renderer_SetModeFunc set_mode */ + NULL /* FT_Raster_Funcs* raster_class */ ) diff --git a/thirdparty/freetype/src/truetype/ttdriver.c b/thirdparty/freetype/src/truetype/ttdriver.c index 4bea63ef84..7151e82073 100644 --- a/thirdparty/freetype/src/truetype/ttdriver.c +++ b/thirdparty/freetype/src/truetype/ttdriver.c @@ -57,7 +57,7 @@ * PROPERTY SERVICE * */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) tt_property_set( FT_Module module, /* TT_Driver */ const char* property_name, const void* value, @@ -93,17 +93,27 @@ interpreter_version = *iv; } - if ( interpreter_version == TT_INTERPRETER_VERSION_35 + switch ( interpreter_version ) + { + case TT_INTERPRETER_VERSION_35: + driver->interpreter_version = TT_INTERPRETER_VERSION_35; + break; + + case TT_INTERPRETER_VERSION_38: #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - || interpreter_version == TT_INTERPRETER_VERSION_38 + driver->interpreter_version = TT_INTERPRETER_VERSION_38; + break; #endif + + case TT_INTERPRETER_VERSION_40: #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - || interpreter_version == TT_INTERPRETER_VERSION_40 + driver->interpreter_version = TT_INTERPRETER_VERSION_40; + break; #endif - ) - driver->interpreter_version = interpreter_version; - else + + default: error = FT_ERR( Unimplemented_Feature ); + } return error; } @@ -114,10 +124,10 @@ } - static FT_Error + FT_CALLBACK_DEF( FT_Error ) tt_property_get( FT_Module module, /* TT_Driver */ const char* property_name, - const void* value ) + void* value ) { FT_Error error = FT_Err_Ok; TT_Driver driver = (TT_Driver)module; @@ -144,8 +154,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( tt_service_properties, - (FT_Properties_SetFunc)tt_property_set, /* set_property */ - (FT_Properties_GetFunc)tt_property_get /* get_property */ + tt_property_set, /* FT_Properties_SetFunc set_property */ + tt_property_get /* FT_Properties_GetFunc get_property */ ) @@ -198,35 +208,35 @@ * * They can be implemented by format-specific interfaces. */ - static FT_Error - tt_get_kerning( FT_Face ttface, /* TT_Face */ + FT_CALLBACK_DEF( FT_Error ) + tt_get_kerning( FT_Face face, /* TT_Face */ FT_UInt left_glyph, FT_UInt right_glyph, FT_Vector* kerning ) { - TT_Face face = (TT_Face)ttface; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + TT_Face ttface = (TT_Face)face; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; kerning->x = 0; kerning->y = 0; if ( sfnt ) - kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); + kerning->x = sfnt->get_kerning( ttface, left_glyph, right_glyph ); return 0; } - static FT_Error - tt_get_advances( FT_Face ttface, + FT_CALLBACK_DEF( FT_Error ) + tt_get_advances( FT_Face face, /* TT_Face */ FT_UInt start, FT_UInt count, FT_Int32 flags, FT_Fixed *advances ) { FT_UInt nn; - TT_Face face = (TT_Face)ttface; + TT_Face ttface = (TT_Face)face; /* XXX: TODO: check for sbits */ @@ -235,8 +245,8 @@ { #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* no fast retrieval for blended MM fonts without VVAR table */ - if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) && - !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && + !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) return FT_THROW( Unimplemented_Feature ); #endif @@ -247,7 +257,7 @@ /* since we don't need `tsb', we use zero for `yMax' parameter */ - TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah ); + TT_Get_VMetrics( ttface, start + nn, 0, &tsb, &ah ); advances[nn] = ah; } } @@ -255,8 +265,8 @@ { #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* no fast retrieval for blended MM fonts without HVAR table */ - if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) && - !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && + !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) return FT_THROW( Unimplemented_Feature ); #endif @@ -266,7 +276,7 @@ FT_UShort aw; - TT_Get_HMetrics( face, start + nn, &lsb, &aw ); + TT_Get_HMetrics( ttface, start + nn, &lsb, &aw ); advances[nn] = aw; } } @@ -290,7 +300,7 @@ #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - static FT_Error + FT_CALLBACK_DEF( FT_Error ) tt_size_select( FT_Size size, FT_ULong strike_index ) { @@ -306,7 +316,7 @@ /* use the scaled metrics, even when tt_size_reset fails */ FT_Select_Metrics( size->face, strike_index ); - tt_size_reset( ttsize, 0 ); /* ignore return value */ + tt_size_reset( ttsize ); /* ignore return value */ } else { @@ -327,7 +337,7 @@ #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) tt_size_request( FT_Size size, FT_Size_Request req ) { @@ -367,7 +377,7 @@ if ( FT_IS_SCALABLE( size->face ) ) { - error = tt_size_reset( ttsize, 0 ); + error = tt_size_reset( ttsize ); #ifdef TT_USE_BYTECODE_INTERPRETER /* for the `MPS' bytecode instruction we need the point size */ @@ -426,15 +436,15 @@ * @Return: * FreeType error code. 0 means success. */ - static FT_Error - tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ - FT_Size ttsize, /* TT_Size */ + FT_CALLBACK_DEF( FT_Error ) + tt_glyph_load( FT_GlyphSlot slot, /* TT_GlyphSlot */ + FT_Size size, /* TT_Size */ FT_UInt glyph_index, FT_Int32 load_flags ) { - TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; - TT_Size size = (TT_Size)ttsize; - FT_Face face = ttslot->face; + TT_GlyphSlot ttslot = (TT_GlyphSlot)slot; + TT_Size ttsize = (TT_Size)size; + FT_Face face = ttslot->face; FT_Error error; @@ -476,12 +486,12 @@ } /* use hinted metrics only if we load a glyph with hinting */ - size->metrics = ( load_flags & FT_LOAD_NO_HINTING ) - ? &ttsize->metrics - : &size->hinted_metrics; + ttsize->metrics = ( load_flags & FT_LOAD_NO_HINTING ) + ? &size->metrics + : &ttsize->hinted_metrics; /* now fill in the glyph slot with outline/bitmap/layered */ - error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); + error = TT_Load_Glyph( ttsize, ttslot, glyph_index, load_flags ); /* force drop-out mode to 2 - irrelevant now */ /* slot->outline.dropout_mode = 2; */ @@ -507,49 +517,47 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, /* get_mm */ - (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */ - (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */ - (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ - (FT_Set_MM_WeightVector_Func) - NULL, /* set_mm_weightvector */ - (FT_Get_MM_WeightVector_Func) - NULL, /* get_mm_weightvector */ - (FT_Var_Load_Delta_Set_Idx_Map_Func) - tt_var_load_delta_set_index_mapping, - /* load_delta_set_idx_map */ - (FT_Var_Load_Item_Var_Store_Func) - tt_var_load_item_variation_store, - /* load_item_variation_store */ - (FT_Var_Get_Item_Delta_Func) - tt_var_get_item_delta, /* get_item_delta */ - (FT_Var_Done_Item_Var_Store_Func) - tt_var_done_item_variation_store, - /* done_item_variation_store */ - (FT_Var_Done_Delta_Set_Idx_Map_Func) - tt_var_done_delta_set_index_map, - /* done_delta_set_index_map */ - (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ - (FT_Done_Blend_Func) tt_done_blend /* done_blend */ + NULL, /* FT_Get_MM_Func get_mm */ + NULL, /* FT_Set_MM_Design_Func set_mm_design */ + TT_Set_MM_Blend, /* FT_Set_MM_Blend_Func set_mm_blend */ + TT_Get_MM_Blend, /* FT_Get_MM_Blend_Func get_mm_blend */ + TT_Get_MM_Var, /* FT_Get_MM_Var_Func get_mm_var */ + TT_Set_Var_Design, /* FT_Set_Var_Design_Func set_var_design */ + TT_Get_Var_Design, /* FT_Get_Var_Design_Func get_var_design */ + TT_Set_Named_Instance, /* FT_Set_Named_Instance_Func set_named_instance */ + TT_Get_Default_Named_Instance, + /* FT_Get_Default_Named_Instance_Func get_default_named_instance */ + NULL, /* FT_Set_MM_WeightVector_Func set_mm_weightvector */ + NULL, /* FT_Get_MM_WeightVector_Func get_mm_weightvector */ + + tt_construct_ps_name, /* FT_Construct_PS_Name_Func construct_ps_name */ + tt_var_load_delta_set_index_mapping, + /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map */ + tt_var_load_item_variation_store, + /* FT_Var_Load_Item_Var_Store_Func load_item_variation_store */ + tt_var_get_item_delta, /* FT_Var_Get_Item_Delta_Func get_item_delta */ + tt_var_done_item_variation_store, + /* FT_Var_Done_Item_Var_Store_Func done_item_variation_store */ + tt_var_done_delta_set_index_map, + /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map */ + tt_get_var_blend, /* FT_Get_Var_Blend_Func get_var_blend */ + tt_done_blend /* FT_Done_Blend_Func done_blend */ ) FT_DEFINE_SERVICE_METRICSVARIATIONSREC( tt_service_metrics_variations, - (FT_HAdvance_Adjust_Func)tt_hadvance_adjust, /* hadvance_adjust */ - (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */ - (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */ + tt_hadvance_adjust, /* FT_HAdvance_Adjust_Func hadvance_adjust */ + NULL, /* FT_LSB_Adjust_Func lsb_adjust */ + NULL, /* FT_RSB_Adjust_Func rsb_adjust */ - (FT_VAdvance_Adjust_Func)tt_vadvance_adjust, /* vadvance_adjust */ - (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */ - (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ - (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ + tt_vadvance_adjust, /* FT_VAdvance_Adjust_Func vadvance_adjust */ + NULL, /* FT_TSB_Adjust_Func tsb_adjust */ + NULL, /* FT_BSB_Adjust_Func bsb_adjust */ + NULL, /* FT_VOrg_Adjust_Func vorg_adjust */ - (FT_Metrics_Adjust_Func) tt_apply_mvar /* metrics_adjust */ + tt_apply_mvar, /* FT_Metrics_Adjust_Func metrics_adjust */ + tt_size_reset_height /* FT_Size_Reset_Func size_reset */ ) #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ diff --git a/thirdparty/freetype/src/truetype/ttgload.c b/thirdparty/freetype/src/truetype/ttgload.c index d33bdad642..5f15a7f4de 100644 --- a/thirdparty/freetype/src/truetype/ttgload.c +++ b/thirdparty/freetype/src/truetype/ttgload.c @@ -362,17 +362,16 @@ FT_Byte* p = load->cursor; FT_Byte* limit = load->limit; FT_GlyphLoader gloader = load->gloader; + FT_Outline* outline = &gloader->current.outline; FT_Int n_contours = load->n_contours; - FT_Outline* outline; - FT_UShort n_ins; FT_Int n_points; + FT_UShort n_ins; FT_Byte *flag, *flag_limit; FT_Byte c, count; FT_Vector *vec, *vec_limit; FT_Pos x, y; - FT_Short *cont, *cont_limit, prev_cont; - FT_Int xy_size = 0; + FT_Short *cont, *cont_limit, last; /* check that we can add the contours to the glyph */ @@ -380,41 +379,27 @@ if ( error ) goto Fail; - /* reading the contours' endpoints & number of points */ - cont = gloader->current.outline.contours; - cont_limit = cont + n_contours; - /* check space for contours array + instructions count */ - if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) + if ( n_contours >= 0xFFF || p + 2 * n_contours + 2 > limit ) goto Invalid_Outline; - prev_cont = FT_NEXT_SHORT( p ); - - if ( n_contours > 0 ) - cont[0] = prev_cont; - - if ( prev_cont < 0 ) - goto Invalid_Outline; + /* reading the contours' endpoints & number of points */ + cont = outline->contours; + cont_limit = cont + n_contours; - for ( cont++; cont < cont_limit; cont++ ) + last = -1; + for ( ; cont < cont_limit; cont++ ) { - cont[0] = FT_NEXT_SHORT( p ); - if ( cont[0] <= prev_cont ) - { - /* unordered contours: this is invalid */ - goto Invalid_Outline; - } - prev_cont = cont[0]; - } + *cont = FT_NEXT_SHORT( p ); - n_points = 0; - if ( n_contours > 0 ) - { - n_points = cont[-1] + 1; - if ( n_points < 0 ) + if ( *cont <= last ) goto Invalid_Outline; + + last = *cont; } + n_points = last + 1; + FT_TRACE5(( " # of points: %d\n", n_points )); /* note that we will add four phantom points later */ @@ -422,59 +407,48 @@ if ( error ) goto Fail; - /* reading the bytecode instructions */ - load->glyph->control_len = 0; - load->glyph->control_data = NULL; - - if ( p + 2 > limit ) - goto Invalid_Outline; - + /* space checked above */ n_ins = FT_NEXT_USHORT( p ); FT_TRACE5(( " Instructions size: %u\n", n_ins )); + /* check instructions size */ + if ( p + n_ins > limit ) + { + FT_TRACE1(( "TT_Load_Simple_Glyph: excessive instruction count\n" )); + error = FT_THROW( Too_Many_Hints ); + goto Fail; + } + #ifdef TT_USE_BYTECODE_INTERPRETER if ( IS_HINTED( load->load_flags ) ) { - FT_ULong tmp; + TT_ExecContext exec = load->exec; + FT_Memory memory = exec->memory; - /* check instructions size */ - if ( ( limit - p ) < n_ins ) - { - FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); - error = FT_THROW( Too_Many_Hints ); - goto Fail; - } + if ( exec->glyphSize ) + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; /* we don't trust `maxSizeOfInstructions' in the `maxp' table */ - /* and thus update the bytecode array size by ourselves */ - - tmp = load->exec->glyphSize; - error = Update_Max( load->exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void*)&load->exec->glyphIns, - n_ins ); - - load->exec->glyphSize = (FT_UInt)tmp; - if ( error ) - return error; + /* and thus allocate the bytecode array size by ourselves */ + if ( n_ins ) + { + if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ) + return error; - load->glyph->control_len = n_ins; - load->glyph->control_data = load->exec->glyphIns; + FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins ); - if ( n_ins ) - FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); + exec->glyphSize = n_ins; + } } #endif /* TT_USE_BYTECODE_INTERPRETER */ p += n_ins; - outline = &gloader->current.outline; - /* reading the point tags */ flag = (FT_Byte*)outline->tags; flag_limit = flag + n_points; @@ -512,9 +486,6 @@ flag = (FT_Byte*)outline->tags; x = 0; - if ( p + xy_size > limit ) - goto Invalid_Outline; - for ( ; vec < vec_limit; vec++, flag++ ) { FT_Pos delta = 0; @@ -544,7 +515,7 @@ /* reading the Y coordinates */ - vec = gloader->current.outline.points; + vec = outline->points; vec_limit = vec + n_points; flag = (FT_Byte*)outline->tags; y = 0; @@ -836,15 +807,14 @@ TT_GlyphZone zone = &loader->zone; #ifdef TT_USE_BYTECODE_INTERPRETER - FT_Long n_ins; + TT_ExecContext exec = loader->exec; + FT_Long n_ins = exec->glyphSize; #else FT_UNUSED( is_composite ); #endif #ifdef TT_USE_BYTECODE_INTERPRETER - n_ins = loader->glyph->control_len; - /* save original point positions in `org' array */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); @@ -856,15 +826,15 @@ /* completely refer to the (already) hinted subglyphs. */ if ( is_composite ) { - loader->exec->metrics.x_scale = 1 << 16; - loader->exec->metrics.y_scale = 1 << 16; + exec->metrics.x_scale = 1 << 16; + exec->metrics.y_scale = 1 << 16; FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); } else { - loader->exec->metrics.x_scale = loader->size->metrics->x_scale; - loader->exec->metrics.y_scale = loader->size->metrics->y_scale; + exec->metrics.x_scale = loader->size->metrics->x_scale; + exec->metrics.y_scale = loader->size->metrics->y_scale; } #endif @@ -884,23 +854,19 @@ { FT_Error error; - FT_GlyphLoader gloader = loader->gloader; - FT_Outline current_outline = gloader->current.outline; + TT_Set_CodeRange( exec, tt_coderange_glyph, exec->glyphIns, n_ins ); - TT_Set_CodeRange( loader->exec, tt_coderange_glyph, - loader->exec->glyphIns, n_ins ); - - loader->exec->is_composite = is_composite; - loader->exec->pts = *zone; + exec->is_composite = is_composite; + exec->pts = *zone; error = TT_Run_Context( loader->exec ); - if ( error && loader->exec->pedantic_hinting ) + if ( error && exec->pedantic_hinting ) return error; /* store drop-out mode in bits 5-7; set bit 2 also as a marker */ - current_outline.tags[0] |= - ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; + loader->gloader->current.outline.tags[0] |= + ( exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; } #endif @@ -910,7 +876,7 @@ /* compatibility mode, where no movement on the x axis means no reason */ /* to change bearings or advance widths. */ if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && - loader->exec->backward_compatibility ) ) + exec->backward_compatibility ) ) { #endif loader->pp1 = zone->cur[zone->n_points - 4]; @@ -924,10 +890,10 @@ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) + if ( exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 ); - else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) + else if ( exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); } #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ @@ -949,10 +915,10 @@ static FT_Error TT_Process_Simple_Glyph( TT_Loader loader ) { - FT_GlyphLoader gloader = loader->gloader; - FT_Error error = FT_Err_Ok; - FT_Outline* outline; - FT_Int n_points; + FT_Error error = FT_Err_Ok; + FT_GlyphLoader gloader = loader->gloader; + FT_Outline* outline = &gloader->current.outline; + FT_Int n_points = outline->n_points; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_Memory memory = loader->face->root.memory; @@ -960,11 +926,7 @@ #endif - outline = &gloader->current.outline; - n_points = outline->n_points; - /* set phantom points */ - outline->points[n_points ] = loader->pp1; outline->points[n_points + 1] = loader->pp2; outline->points[n_points + 2] = loader->pp3; @@ -976,7 +938,7 @@ if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) ) { - if ( FT_NEW_ARRAY( unrounded, n_points ) ) + if ( FT_QNEW_ARRAY( unrounded, n_points ) ) goto Exit; /* Deltas apply to the unscaled data. */ @@ -1331,12 +1293,12 @@ FT_UInt start_contour ) { FT_Error error; - FT_Outline* outline; + FT_Outline* outline = &loader->gloader->base.outline; + FT_Stream stream = loader->stream; + FT_UShort n_ins; FT_UInt i; - outline = &loader->gloader->base.outline; - /* make room for phantom points */ error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader, outline->n_points + 4, @@ -1352,10 +1314,13 @@ #ifdef TT_USE_BYTECODE_INTERPRETER { - FT_Stream stream = loader->stream; - FT_UShort n_ins, max_ins; - FT_ULong tmp; + TT_ExecContext exec = loader->exec; + FT_Memory memory = exec->memory; + + if ( exec->glyphSize ) + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; /* TT_Load_Composite_Glyph only gives us the offset of instructions */ /* so we read them here */ @@ -1365,39 +1330,24 @@ FT_TRACE5(( " Instructions size = %hu\n", n_ins )); - /* check it */ - max_ins = loader->face->max_profile.maxSizeOfInstructions; - if ( n_ins > max_ins ) - { - /* don't trust `maxSizeOfInstructions'; */ - /* only do a rough safety check */ - if ( n_ins > loader->byte_len ) - { - FT_TRACE1(( "TT_Process_Composite_Glyph:" - " too many instructions (%hu) for glyph with length %u\n", - n_ins, loader->byte_len )); - return FT_THROW( Too_Many_Hints ); - } - - tmp = loader->exec->glyphSize; - error = Update_Max( loader->exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void*)&loader->exec->glyphIns, - n_ins ); + if ( !n_ins ) + return FT_Err_Ok; - loader->exec->glyphSize = (FT_UShort)tmp; - if ( error ) - return error; + /* don't trust `maxSizeOfInstructions'; */ + /* only do a rough safety check */ + if ( n_ins > loader->byte_len ) + { + FT_TRACE1(( "TT_Process_Composite_Glyph:" + " too many instructions (%hu) for glyph with length %u\n", + n_ins, loader->byte_len )); + return FT_THROW( Too_Many_Hints ); } - else if ( n_ins == 0 ) - return FT_Err_Ok; - if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) ) + if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) || + FT_STREAM_READ( exec->glyphIns, n_ins ) ) return error; - loader->glyph->control_data = loader->exec->glyphIns; - loader->glyph->control_len = n_ins; + exec->glyphSize = n_ins; } #endif @@ -1662,8 +1612,14 @@ else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + FT_ULong len; + - offset = tt_face_get_location( face, glyph_index, &loader->byte_len ); + offset = tt_face_get_location( FT_FACE( face ), glyph_index, &len ); + + loader->byte_len = (FT_UInt)len; + } if ( loader->byte_len > 0 ) { @@ -1889,10 +1845,7 @@ short i, limit; FT_SubGlyph subglyph; - FT_Outline outline; - FT_Vector* points = NULL; - char* tags = NULL; - short* contours = NULL; + FT_Outline outline = { 0, 0, NULL, NULL, NULL, 0 }; FT_Vector* unrounded = NULL; @@ -1900,18 +1853,14 @@ /* construct an outline structure for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ - outline.n_contours = outline.n_points = limit; - - outline.points = NULL; - outline.tags = NULL; - outline.contours = NULL; - - if ( FT_NEW_ARRAY( points, limit + 4 ) || - FT_NEW_ARRAY( tags, limit + 4 ) || - FT_NEW_ARRAY( contours, limit + 4 ) || - FT_NEW_ARRAY( unrounded, limit + 4 ) ) + if ( FT_QNEW_ARRAY( outline.points, limit + 4 ) || + FT_QNEW_ARRAY( outline.tags, limit ) || + FT_QNEW_ARRAY( outline.contours, limit ) || + FT_QNEW_ARRAY( unrounded, limit + 4 ) ) goto Exit1; + outline.n_contours = outline.n_points = limit; + subglyph = gloader->current.subglyphs; for ( i = 0; i < limit; i++, subglyph++ ) @@ -1919,20 +1868,16 @@ /* applying deltas for anchor points doesn't make sense, */ /* but we don't have to specially check this since */ /* unused delta values are zero anyways */ - points[i].x = subglyph->arg1; - points[i].y = subglyph->arg2; - tags[i] = 1; - contours[i] = i; + outline.points[i].x = subglyph->arg1; + outline.points[i].y = subglyph->arg2; + outline.tags[i] = ON_CURVE_POINT; + outline.contours[i] = i; } - points[i++] = loader->pp1; - points[i++] = loader->pp2; - points[i++] = loader->pp3; - points[i ] = loader->pp4; - - outline.points = points; - outline.tags = tags; - outline.contours = contours; + outline.points[i++] = loader->pp1; + outline.points[i++] = loader->pp2; + outline.points[i++] = loader->pp3; + outline.points[i ] = loader->pp4; /* this call provides additional offsets */ /* for each component's translation */ @@ -1947,8 +1892,8 @@ { if ( subglyph->flags & ARGS_ARE_XY_VALUES ) { - subglyph->arg1 = (FT_Int16)points[i].x; - subglyph->arg2 = (FT_Int16)points[i].y; + subglyph->arg1 = (FT_Int16)outline.points[i].x; + subglyph->arg2 = (FT_Int16)outline.points[i].y; } } @@ -2857,7 +2802,9 @@ #ifdef FT_CONFIG_OPTION_SVG /* check for OT-SVG */ - if ( ( load_flags & FT_LOAD_COLOR ) && face->svg ) + if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 && + ( load_flags & FT_LOAD_COLOR ) && + face->svg ) { SFNT_Service sfnt = (SFNT_Service)face->sfnt; @@ -2955,6 +2902,9 @@ if ( IS_HINTED( load_flags ) ) { + glyph->control_data = loader.exec->glyphIns; + glyph->control_len = loader.exec->glyphSize; + if ( loader.exec->GS.scan_control ) { /* convert scan conversion mode to FT_OUTLINE_XXX flags */ diff --git a/thirdparty/freetype/src/truetype/ttgxvar.c b/thirdparty/freetype/src/truetype/ttgxvar.c index 60a0095b6e..8c713f1b6f 100644 --- a/thirdparty/freetype/src/truetype/ttgxvar.c +++ b/thirdparty/freetype/src/truetype/ttgxvar.c @@ -45,6 +45,7 @@ #include <freetype/internal/ftcalc.h> #include <freetype/internal/ftstream.h> #include <freetype/internal/sfnt.h> +#include <freetype/internal/services/svmetric.h> #include <freetype/tttags.h> #include <freetype/ttnameid.h> #include <freetype/ftmm.h> @@ -465,7 +466,7 @@ if ( store_offset ) { error = tt_var_load_item_variation_store( - face, + FT_FACE( face ), table_offset + store_offset, &table->itemStore ); if ( error ) @@ -475,7 +476,7 @@ if ( axisMap_offset ) { error = tt_var_load_delta_set_index_mapping( - face, + FT_FACE( face ), table_offset + axisMap_offset, &table->axisMap, &table->itemStore, @@ -492,10 +493,11 @@ FT_LOCAL_DEF( FT_Error ) - tt_var_load_item_variation_store( TT_Face face, + tt_var_load_item_variation_store( FT_Face face, /* TT_Face */ FT_ULong offset, GX_ItemVarStore itemStore ) { + TT_Face ttface = (TT_Face)face; FT_Stream stream = FT_FACE_STREAM( face ); FT_Memory memory = stream->memory; @@ -507,10 +509,10 @@ FT_UShort axis_count; FT_UInt region_count; - FT_UInt i, j, k; + FT_UInt i, j; FT_Bool long_words; - GX_Blend blend = face->blend; + GX_Blend blend = ttface->blend; FT_ULong* dataOffsetArray = NULL; @@ -622,6 +624,7 @@ FT_UInt item_count; FT_UInt word_delta_count; FT_UInt region_idx_count; + FT_UInt per_region_size; if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) ) @@ -658,6 +661,8 @@ if ( FT_NEW_ARRAY( varData->regionIndices, region_idx_count ) ) goto Exit; varData->regionIdxCount = region_idx_count; + varData->wordDeltaCount = word_delta_count; + varData->longWords = long_words; for ( j = 0; j < varData->regionIdxCount; j++ ) { @@ -673,37 +678,22 @@ } } - /* Parse delta set. */ - /* */ - /* On input, deltas are (word_delta_count + region_idx_count) bytes */ - /* each if `long_words` isn't set, and twice as much otherwise. */ - /* */ - /* On output, deltas are expanded to `region_idx_count` shorts each. */ - if ( FT_NEW_ARRAY( varData->deltaSet, item_count * region_idx_count ) ) - goto Exit; - varData->itemCount = item_count; + per_region_size = word_delta_count + region_idx_count; + if ( long_words ) + per_region_size *= 2; - for ( j = 0; j < item_count * region_idx_count; ) + if ( FT_NEW_ARRAY( varData->deltaSet, per_region_size * item_count ) ) + goto Exit; + if ( FT_Stream_Read( stream, + varData->deltaSet, + per_region_size * item_count ) ) { - if ( long_words ) - { - for ( k = 0; k < word_delta_count; k++, j++ ) - if ( FT_READ_LONG( varData->deltaSet[j] ) ) - goto Exit; - for ( ; k < region_idx_count; k++, j++ ) - if ( FT_READ_SHORT( varData->deltaSet[j] ) ) - goto Exit; - } - else - { - for ( k = 0; k < word_delta_count; k++, j++ ) - if ( FT_READ_SHORT( varData->deltaSet[j] ) ) - goto Exit; - for ( ; k < region_idx_count; k++, j++ ) - if ( FT_READ_CHAR( varData->deltaSet[j] ) ) - goto Exit; - } + FT_TRACE2(( "deltaSet read failed." )); + error = FT_THROW( Invalid_Table ); + goto Exit; } + + varData->itemCount = item_count; } Exit: @@ -714,7 +704,7 @@ FT_LOCAL_DEF( FT_Error ) - tt_var_load_delta_set_index_mapping( TT_Face face, + tt_var_load_delta_set_index_mapping( FT_Face face, /* TT_Face */ FT_ULong offset, GX_DeltaSetIdxMap map, GX_ItemVarStore itemStore, @@ -941,7 +931,7 @@ } error = tt_var_load_item_variation_store( - face, + FT_FACE( face ), table_offset + store_offset, &table->itemStore ); if ( error ) @@ -950,7 +940,7 @@ if ( widthMap_offset ) { error = tt_var_load_delta_set_index_mapping( - face, + FT_FACE( face ), table_offset + widthMap_offset, &table->widthMap, &table->itemStore, @@ -992,24 +982,30 @@ FT_LOCAL_DEF( FT_ItemVarDelta ) - tt_var_get_item_delta( TT_Face face, + tt_var_get_item_delta( FT_Face face, /* TT_Face */ GX_ItemVarStore itemStore, FT_UInt outerIndex, FT_UInt innerIndex ) { + TT_Face ttface = (TT_Face)face; FT_Stream stream = FT_FACE_STREAM( face ); FT_Memory memory = stream->memory; FT_Error error = FT_Err_Ok; GX_ItemVarData varData; - FT_ItemVarDelta* deltaSet; + FT_ItemVarDelta* deltaSet = NULL; + FT_ItemVarDelta deltaSetStack[16]; + + FT_Fixed* scalars = NULL; + FT_Fixed scalarsStack[16]; FT_UInt master, j; - FT_Fixed* scalars = NULL; - FT_ItemVarDelta returnValue; + FT_ItemVarDelta returnValue = 0; + FT_UInt per_region_size; + FT_Byte* bytes; - if ( !face->blend || !face->blend->normalizedcoords ) + if ( !ttface->blend || !ttface->blend->normalizedcoords ) return 0; /* OpenType 1.8.4+: No variation data for this item */ @@ -1023,15 +1019,48 @@ if ( outerIndex >= itemStore->dataCount ) return 0; /* Out of range. */ - varData = &itemStore->varData[outerIndex]; - deltaSet = FT_OFFSET( varData->deltaSet, - varData->regionIdxCount * innerIndex ); + varData = &itemStore->varData[outerIndex]; if ( innerIndex >= varData->itemCount ) return 0; /* Out of range. */ - if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) ) - return 0; + if ( varData->regionIdxCount < 16 ) + { + deltaSet = deltaSetStack; + scalars = scalarsStack; + } + else + { + if ( FT_QNEW_ARRAY( deltaSet, varData->regionIdxCount ) ) + goto Exit; + if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) ) + goto Exit; + } + + /* Parse delta set. */ + /* */ + /* Deltas are (word_delta_count + region_idx_count) bytes each */ + /* if `longWords` isn't set, and twice as much otherwise. */ + per_region_size = varData->wordDeltaCount + varData->regionIdxCount; + if ( varData->longWords ) + per_region_size *= 2; + + bytes = varData->deltaSet + per_region_size * innerIndex; + + if ( varData->longWords ) + { + for ( master = 0; master < varData->wordDeltaCount; master++ ) + deltaSet[master] = FT_NEXT_LONG( bytes ); + for ( ; master < varData->regionIdxCount; master++ ) + deltaSet[master] = FT_NEXT_SHORT( bytes ); + } + else + { + for ( master = 0; master < varData->wordDeltaCount; master++ ) + deltaSet[master] = FT_NEXT_SHORT( bytes ); + for ( ; master < varData->regionIdxCount; master++ ) + deltaSet[master] = FT_NEXT_CHAR( bytes ); + } /* outer loop steps through master designs to be blended */ for ( master = 0; master < varData->regionIdxCount; master++ ) @@ -1060,27 +1089,27 @@ else if ( axis->peakCoord == 0 ) continue; - else if ( face->blend->normalizedcoords[j] == axis->peakCoord ) + else if ( ttface->blend->normalizedcoords[j] == axis->peakCoord ) continue; /* ignore this region if coords are out of range */ - else if ( face->blend->normalizedcoords[j] <= axis->startCoord || - face->blend->normalizedcoords[j] >= axis->endCoord ) + else if ( ttface->blend->normalizedcoords[j] <= axis->startCoord || + ttface->blend->normalizedcoords[j] >= axis->endCoord ) { scalar = 0; break; } /* cumulative product of all the axis scalars */ - else if ( face->blend->normalizedcoords[j] < axis->peakCoord ) + else if ( ttface->blend->normalizedcoords[j] < axis->peakCoord ) scalar = FT_MulDiv( scalar, - face->blend->normalizedcoords[j] - axis->startCoord, + ttface->blend->normalizedcoords[j] - axis->startCoord, axis->peakCoord - axis->startCoord ); else scalar = FT_MulDiv( scalar, - axis->endCoord - face->blend->normalizedcoords[j], + axis->endCoord - ttface->blend->normalizedcoords[j], axis->endCoord - axis->peakCoord ); } /* per-axis loop */ @@ -1106,7 +1135,11 @@ */ returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount ); - FT_FREE( scalars ); + Exit: + if ( scalars != scalarsStack ) + FT_FREE( scalars ); + if ( deltaSet != deltaSetStack ) + FT_FREE( deltaSet ); return returnValue; } @@ -1206,7 +1239,7 @@ innerIndex = gindex; } - delta = tt_var_get_item_delta( face, + delta = tt_var_get_item_delta( FT_FACE( face ), &table->itemStore, outerIndex, innerIndex ); @@ -1229,20 +1262,20 @@ FT_LOCAL_DEF( FT_Error ) - tt_hadvance_adjust( TT_Face face, + tt_hadvance_adjust( FT_Face face, /* TT_Face */ FT_UInt gindex, FT_Int *avalue ) { - return tt_hvadvance_adjust( face, gindex, avalue, 0 ); + return tt_hvadvance_adjust( (TT_Face)face, gindex, avalue, 0 ); } FT_LOCAL_DEF( FT_Error ) - tt_vadvance_adjust( TT_Face face, + tt_vadvance_adjust( FT_Face face, /* TT_Face */ FT_UInt gindex, FT_Int *avalue ) { - return tt_hvadvance_adjust( face, gindex, avalue, 1 ); + return tt_hvadvance_adjust( (TT_Face)face, gindex, avalue, 1 ); } @@ -1389,7 +1422,7 @@ records_offset = FT_STREAM_POS(); error = tt_var_load_item_variation_store( - face, + FT_FACE( face ), table_offset + store_offset, &blend->mvar_table->itemStore ); if ( error ) @@ -1462,15 +1495,14 @@ static FT_Error - tt_size_reset_iterator( FT_ListNode node, + ft_size_reset_iterator( FT_ListNode node, void* user ) { - TT_Size size = (TT_Size)node->data; - - FT_UNUSED( user ); + FT_Size size = (FT_Size)node->data; + FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)user; - tt_size_reset( size, 1 ); + var->size_reset( size ); return FT_Err_Ok; } @@ -1489,16 +1521,19 @@ * The font face. */ FT_LOCAL_DEF( void ) - tt_apply_mvar( TT_Face face ) + tt_apply_mvar( FT_Face face ) /* TT_Face */ { - GX_Blend blend = face->blend; + TT_Face ttface = (TT_Face)face; + + GX_Blend blend = ttface->blend; GX_Value value, limit; + FT_Short mvar_hasc_delta = 0; FT_Short mvar_hdsc_delta = 0; FT_Short mvar_hlgp_delta = 0; - if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) ) + if ( !( ttface->variation_support & TT_FACE_FLAG_VAR_MVAR ) ) return; value = blend->mvar_table->values; @@ -1506,7 +1541,7 @@ for ( ; value < limit; value++ ) { - FT_Short* p = ft_var_get_value_pointer( face, value->tag ); + FT_Short* p = ft_var_get_value_pointer( ttface, value->tag ); FT_Int delta; @@ -1543,7 +1578,8 @@ /* adjust all derived values */ { - FT_Face root = &face->root; + FT_Service_MetricsVariations var = + (FT_Service_MetricsVariations)ttface->face_var; /* * Apply the deltas of hasc, hdsc and hlgp to the FT_Face's ascender, @@ -1571,24 +1607,25 @@ * whether they were actually changed or the font had the OS/2 table's * fsSelection's bit 7 (USE_TYPO_METRICS) set. */ - FT_Short current_line_gap = root->height - root->ascender + - root->descender; + FT_Short current_line_gap = face->height - face->ascender + + face->descender; - root->ascender = root->ascender + mvar_hasc_delta; - root->descender = root->descender + mvar_hdsc_delta; - root->height = root->ascender - root->descender + + face->ascender = face->ascender + mvar_hasc_delta; + face->descender = face->descender + mvar_hdsc_delta; + face->height = face->ascender - face->descender + current_line_gap + mvar_hlgp_delta; - root->underline_position = face->postscript.underlinePosition - - face->postscript.underlineThickness / 2; - root->underline_thickness = face->postscript.underlineThickness; + face->underline_position = ttface->postscript.underlinePosition - + ttface->postscript.underlineThickness / 2; + face->underline_thickness = ttface->postscript.underlineThickness; - /* iterate over all FT_Size objects and call `tt_size_reset' */ - /* to propagate the metrics changes */ - FT_List_Iterate( &root->sizes_list, - tt_size_reset_iterator, - NULL ); + /* iterate over all FT_Size objects and call `var->size_reset' */ + /* to propagate the metrics changes */ + if ( var && var->size_reset ) + FT_List_Iterate( &face->sizes_list, + ft_size_reset_iterator, + (void*)var ); } } @@ -2099,7 +2136,7 @@ innerIndex = table->axisMap.innerIndex[idx]; } - delta = tt_var_get_item_delta( face, + delta = tt_var_get_item_delta( FT_FACE( face ), &table->itemStore, outerIndex, innerIndex ); @@ -2261,11 +2298,12 @@ * FreeType error code. 0 means success. */ FT_LOCAL_DEF( FT_Error ) - TT_Get_MM_Var( TT_Face face, + TT_Get_MM_Var( FT_Face face, /* TT_Face */ FT_MM_Var* *master ) { - FT_Stream stream = face->root.stream; - FT_Memory memory = face->root.memory; + TT_Face ttface = (TT_Face)face; + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = FT_FACE_MEMORY( face ); FT_ULong table_len; FT_Error error = FT_Err_Ok; FT_ULong fvar_start = 0; @@ -2329,19 +2367,19 @@ /* the default instance, which might be missing in the table of named */ /* instances (in 'fvar'). This value is validated in `sfobjs.c` and */ /* may be reset to 0 if consistency checks fail. */ - num_instances = (FT_UInt)face->root.style_flags >> 16; + num_instances = (FT_UInt)face->style_flags >> 16; /* read the font data and set up the internal representation */ /* if not already done */ - need_init = !face->blend; + need_init = !ttface->blend; if ( need_init ) { FT_TRACE2(( "FVAR " )); - if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar, - stream, &table_len ) ) ) + if ( FT_SET_ERROR( ttface->goto_table( ttface, TTAG_fvar, + stream, &table_len ) ) ) { FT_TRACE1(( "is missing\n" )); goto Exit; @@ -2374,14 +2412,14 @@ fvar_head.axisCount, fvar_head.axisCount == 1 ? "is" : "es" )); - if ( FT_NEW( face->blend ) ) + if ( FT_NEW( ttface->blend ) ) goto Exit; - num_axes = fvar_head.axisCount; - face->blend->num_axis = num_axes; + num_axes = fvar_head.axisCount; + ttface->blend->num_axis = num_axes; } else - num_axes = face->blend->num_axis; + num_axes = ttface->blend->num_axis; /* prepare storage area for MM data; this cannot overflow */ /* 32-bit arithmetic because of the size limits used in the */ @@ -2410,16 +2448,16 @@ if ( need_init ) { - face->blend->mmvar_len = mmvar_size + - axis_flags_size + - axis_size + - namedstyle_size + - next_coords_size + - next_name_size; - - if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + ttface->blend->mmvar_len = mmvar_size + + axis_flags_size + + axis_size + + namedstyle_size + + next_coords_size + + next_name_size; + + if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) ) goto Exit; - face->blend->mmvar = mmvar; + ttface->blend->mmvar = mmvar; /* set up pointers and offsets into the `mmvar' array; */ /* the data gets filled in later on */ @@ -2525,27 +2563,27 @@ /* named instance coordinates are stored as design coordinates; */ /* we have to convert them to normalized coordinates also */ - if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords, + if ( FT_NEW_ARRAY( ttface->blend->normalized_stylecoords, num_axes * num_instances ) ) goto Exit; - if ( fvar_head.instanceCount && !face->blend->avar_loaded ) + if ( fvar_head.instanceCount && !ttface->blend->avar_loaded ) { FT_ULong offset = FT_STREAM_POS(); - ft_var_load_avar( face ); + ft_var_load_avar( ttface ); if ( FT_STREAM_SEEK( offset ) ) goto Exit; } - FT_TRACE5(( "%d instance%s\n", + FT_TRACE5(( "%d named instance%s\n", fvar_head.instanceCount, fvar_head.instanceCount == 1 ? "" : "s" )); ns = mmvar->namedstyle; - nsc = face->blend->normalized_stylecoords; + nsc = ttface->blend->normalized_stylecoords; for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) { /* PostScript names add 2 bytes to the instance record size */ @@ -2568,7 +2606,7 @@ #ifdef FT_DEBUG_LEVEL_TRACE { - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_String* strname = NULL; FT_String* psname = NULL; @@ -2580,7 +2618,7 @@ if ( ns->strid != 0xFFFF ) { - (void)sfnt->get_name( face, + (void)sfnt->get_name( ttface, (FT_UShort)ns->strid, &strname ); if ( strname && !ft_strcmp( strname, ".notdef" ) ) @@ -2589,7 +2627,7 @@ if ( ns->psid != 0xFFFF ) { - (void)sfnt->get_name( face, + (void)sfnt->get_name( ttface, (FT_UShort)ns->psid, &psname ); if ( psname && !ft_strcmp( psname, ".notdef" ) ) @@ -2598,7 +2636,7 @@ (void)FT_STREAM_SEEK( pos ); - FT_TRACE5(( " instance %d (%s%s%s, %s%s%s)\n", + FT_TRACE5(( " named instance %d (%s%s%s, %s%s%s)\n", i, strname ? "name: `" : "", strname ? strname : "unnamed", @@ -2612,7 +2650,7 @@ } #endif /* FT_DEBUG_LEVEL_TRACE */ - ft_var_to_normalized( face, num_axes, ns->coords, nsc ); + ft_var_to_normalized( ttface, num_axes, ns->coords, nsc ); nsc += num_axes; FT_FRAME_EXIT(); @@ -2620,15 +2658,17 @@ if ( num_instances != fvar_head.instanceCount ) { - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_Int found, dummy1, dummy2; FT_UInt strid = ~0U; - /* the default instance is missing in array the */ - /* of named instances; try to synthesize an entry */ - found = sfnt->get_name_id( face, + /* The default instance is missing in array the */ + /* of named instances; try to synthesize an entry. */ + /* If this fails, `default_named_instance` remains */ + /* at value zero, which doesn't do any harm. */ + found = sfnt->get_name_id( ttface, TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY, &dummy1, &dummy2 ); @@ -2636,7 +2676,7 @@ strid = TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY; else { - found = sfnt->get_name_id( face, + found = sfnt->get_name_id( ttface, TT_NAME_ID_FONT_SUBFAMILY, &dummy1, &dummy2 ); @@ -2646,7 +2686,7 @@ if ( found ) { - found = sfnt->get_name_id( face, + found = sfnt->get_name_id( ttface, TT_NAME_ID_PS_NAME, &dummy1, &dummy2 ); @@ -2655,6 +2695,9 @@ FT_TRACE5(( "TT_Get_MM_Var:" " Adding default instance to named instances\n" )); + /* named instance indices start with value 1 */ + ttface->var_default_named_instance = num_instances; + ns = &mmvar->namedstyle[fvar_head.instanceCount]; ns->strid = strid; @@ -2668,7 +2711,7 @@ } } - ft_var_load_mvar( face ); + ft_var_load_mvar( ttface ); } /* fill the output array if requested */ @@ -2678,9 +2721,9 @@ FT_UInt n; - if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) ) goto Exit; - FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); + FT_MEM_COPY( mmvar, ttface->blend->mmvar, ttface->blend->mmvar_len ); axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size ); @@ -2756,7 +2799,7 @@ if ( !face->blend ) { - if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + if ( FT_SET_ERROR( TT_Get_MM_Var( FT_FACE( face ), NULL ) ) ) goto Exit; } @@ -2841,26 +2884,29 @@ } } - if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + if ( !have_diff ) { - FT_UInt instance_index = (FT_UInt)face->root.face_index >> 16; + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + { + FT_UInt instance_index = (FT_UInt)face->root.face_index >> 16; - c = blend->normalizedcoords + i; - n = blend->normalized_stylecoords + - ( instance_index - 1 ) * mmvar->num_axis + - i; + c = blend->normalizedcoords + i; + n = blend->normalized_stylecoords + + ( instance_index - 1 ) * mmvar->num_axis + + i; - for ( j = i; j < mmvar->num_axis; j++, n++, c++ ) - if ( *c != *n ) - have_diff = 1; - } - else - { - c = blend->normalizedcoords + i; - for ( j = i; j < mmvar->num_axis; j++, c++ ) - if ( *c != 0 ) - have_diff = 1; + for ( j = i; j < mmvar->num_axis; j++, n++, c++ ) + if ( *c != *n ) + have_diff = 1; + } + else + { + c = blend->normalizedcoords + i; + for ( j = i; j < mmvar->num_axis; j++, c++ ) + if ( *c != 0 ) + have_diff = 1; + } } /* return value -1 indicates `no change' */ @@ -2924,9 +2970,6 @@ } } - /* enforce recomputation of the PostScript name; */ - FT_FREE( face->postscript_name ); - Exit: return error; } @@ -2958,26 +3001,15 @@ * An array of `num_coords', each between [-1,1]. * * @Return: - * FreeType error code. 0 means success. + * FreeType error code. 0 means success, -1 means success and unchanged + * axis values. */ FT_LOCAL_DEF( FT_Error ) - TT_Set_MM_Blend( TT_Face face, + TT_Set_MM_Blend( FT_Face face, /* TT_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error; - - - error = tt_set_mm_blend( face, num_coords, coords, 1 ); - if ( error ) - return error; - - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - - return FT_Err_Ok; + return tt_set_mm_blend( (TT_Face)face, num_coords, coords, 1 ); } @@ -3005,31 +3037,34 @@ * An array of `num_coords', each between [-1,1]. * * @Return: - * FreeType error code. 0 means success. + * FreeType error code. 0 means success, -1 means success and unchanged + * axis values. */ FT_LOCAL_DEF( FT_Error ) - TT_Get_MM_Blend( TT_Face face, + TT_Get_MM_Blend( FT_Face face, /* TT_Face */ FT_UInt num_coords, FT_Fixed* coords ) { + TT_Face ttface = (TT_Face)face; + FT_Error error = FT_Err_Ok; GX_Blend blend; FT_UInt i, nc; - if ( !face->blend ) + if ( !ttface->blend ) { if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) return error; } - blend = face->blend; + blend = ttface->blend; if ( !blend->coords ) { /* select default instance coordinates */ /* if no instance is selected yet */ - if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) ) + if ( FT_SET_ERROR( tt_set_mm_blend( ttface, 0, NULL, 1 ) ) ) return error; } @@ -3042,7 +3077,7 @@ nc = blend->num_axis; } - if ( face->doblend ) + if ( ttface->doblend ) { for ( i = 0; i < nc; i++ ) coords[i] = blend->normalizedcoords[i]; @@ -3089,15 +3124,16 @@ * FreeType error code. 0 means success. */ FT_LOCAL_DEF( FT_Error ) - TT_Set_Var_Design( TT_Face face, + TT_Set_Var_Design( FT_Face face, /* TT_Face */ FT_UInt num_coords, FT_Fixed* coords ) { + TT_Face ttface = (TT_Face)face; FT_Error error = FT_Err_Ok; GX_Blend blend; FT_MM_Var* mmvar; FT_UInt i; - FT_Memory memory = face->root.memory; + FT_Memory memory = FT_FACE_MEMORY( face ); FT_Fixed* c; FT_Fixed* n; @@ -3106,13 +3142,13 @@ FT_Bool have_diff = 0; - if ( !face->blend ) + if ( !ttface->blend ) { if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) goto Exit; } - blend = face->blend; + blend = ttface->blend; mmvar = blend->mmvar; if ( num_coords > mmvar->num_axis ) @@ -3140,13 +3176,13 @@ } } - if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + if ( FT_IS_NAMED_INSTANCE( face ) ) { FT_UInt instance_index; FT_Var_Named_Style* named_style; - instance_index = (FT_UInt)face->root.face_index >> 16; + instance_index = (FT_UInt)face->face_index >> 16; named_style = mmvar->namedstyle + instance_index - 1; n = named_style->coords + num_coords; @@ -3183,22 +3219,17 @@ if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) goto Exit; - if ( !face->blend->avar_loaded ) - ft_var_load_avar( face ); + if ( !ttface->blend->avar_loaded ) + ft_var_load_avar( ttface ); FT_TRACE5(( "TT_Set_Var_Design:\n" )); FT_TRACE5(( " normalized design coordinates:\n" )); - ft_var_to_normalized( face, num_coords, blend->coords, normalized ); + ft_var_to_normalized( ttface, num_coords, blend->coords, normalized ); - error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 ); + error = tt_set_mm_blend( ttface, mmvar->num_axis, normalized, 0 ); if ( error ) goto Exit; - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - Exit: FT_FREE( normalized ); return error; @@ -3231,28 +3262,29 @@ * FreeType error code. 0~means success. */ FT_LOCAL_DEF( FT_Error ) - TT_Get_Var_Design( TT_Face face, + TT_Get_Var_Design( FT_Face face, /* TT_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error = FT_Err_Ok; + TT_Face ttface = (TT_Face)face; + FT_Error error = FT_Err_Ok; GX_Blend blend; FT_UInt i, nc; - if ( !face->blend ) + if ( !ttface->blend ) { if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) return error; } - blend = face->blend; + blend = ttface->blend; if ( !blend->coords ) { /* select default instance coordinates */ /* if no instance is selected yet */ - if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) ) + if ( FT_SET_ERROR( tt_set_mm_blend( ttface, 0, NULL, 1 ) ) ) return error; } @@ -3265,7 +3297,7 @@ nc = blend->num_axis; } - if ( face->doblend ) + if ( ttface->doblend ) { for ( i = 0; i < nc; i++ ) coords[i] = blend->coords[i]; @@ -3301,29 +3333,33 @@ * Value 0 indicates to not use an instance. * * @Return: - * FreeType error code. 0~means success. + * FreeType error code. 0~means success, -1 means success and unchanged + * axis values. */ FT_LOCAL_DEF( FT_Error ) - TT_Set_Named_Instance( TT_Face face, + TT_Set_Named_Instance( FT_Face face, /* TT_Face */ FT_UInt instance_index ) { + TT_Face ttface = (TT_Face)face; FT_Error error; GX_Blend blend; FT_MM_Var* mmvar; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_UInt num_instances; - if ( !face->blend ) + if ( !ttface->blend ) { if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) goto Exit; } - blend = face->blend; + blend = ttface->blend; mmvar = blend->mmvar; - num_instances = (FT_UInt)face->root.style_flags >> 16; + num_instances = (FT_UInt)face->style_flags >> 16; /* `instance_index' starts with value 1, thus `>' */ if ( instance_index > num_instances ) @@ -3334,8 +3370,7 @@ if ( instance_index > 0 ) { - FT_Memory memory = face->root.memory; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_Var_Named_Style* named_style; FT_String* style_name; @@ -3343,40 +3378,89 @@ named_style = mmvar->namedstyle + instance_index - 1; - error = sfnt->get_name( face, + error = sfnt->get_name( ttface, (FT_UShort)named_style->strid, &style_name ); if ( error ) goto Exit; /* set (or replace) style name */ - FT_FREE( face->root.style_name ); - face->root.style_name = style_name; + FT_FREE( face->style_name ); + face->style_name = style_name; /* finally, select the named instance */ error = TT_Set_Var_Design( face, mmvar->num_axis, named_style->coords ); - if ( error ) - { - /* internal error code -1 means `no change' */ - if ( error == -1 ) - error = FT_Err_Ok; - goto Exit; - } } else + { + /* restore non-VF style name */ + FT_FREE( face->style_name ); + if ( FT_STRDUP( face->style_name, ttface->non_var_style_name ) ) + goto Exit; error = TT_Set_Var_Design( face, 0, NULL ); + } + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * TT_Get_Default_Named_Instance + * + * @Description: + * Get the default named instance. + * + * @Input: + * face :: + * A handle to the source face. + * + * @Output: + * instance_index :: + * The default named instance index. + * + * @Return: + * FreeType error code. 0~means success. + */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_Default_Named_Instance( FT_Face face, + FT_UInt *instance_index ) + { + TT_Face ttface = (TT_Face)face; + FT_Error error = FT_Err_Ok; - face->root.face_index = ( instance_index << 16 ) | - ( face->root.face_index & 0xFFFFL ); - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; + + if ( !ttface->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + goto Exit; + } + + *instance_index = ttface->var_default_named_instance; Exit: return error; } + /* This function triggers (lazy) recomputation of the `postscript_name` */ + /* field in `TT_Face`. */ + + FT_LOCAL_DEF( void ) + tt_construct_ps_name( FT_Face face ) + { + TT_Face ttface = (TT_Face)face; + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( ttface->postscript_name ); + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -4409,22 +4493,25 @@ * the MM machinery in case it isn't loaded yet. */ FT_LOCAL_DEF( FT_Error ) - tt_get_var_blend( TT_Face face, + tt_get_var_blend( FT_Face face, /* TT_Face */ FT_UInt *num_coords, FT_Fixed* *coords, FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ) { - if ( face->blend ) + TT_Face ttface = (TT_Face)face; + + + if ( ttface->blend ) { if ( num_coords ) - *num_coords = face->blend->num_axis; + *num_coords = ttface->blend->num_axis; if ( coords ) - *coords = face->blend->coords; + *coords = ttface->blend->coords; if ( normalizedcoords ) - *normalizedcoords = face->blend->normalizedcoords; + *normalizedcoords = ttface->blend->normalizedcoords; if ( mm_var ) - *mm_var = face->blend->mmvar; + *mm_var = ttface->blend->mmvar; } else { @@ -4441,7 +4528,7 @@ FT_LOCAL_DEF( void ) - tt_var_done_item_variation_store( TT_Face face, + tt_var_done_item_variation_store( FT_Face face, GX_ItemVarStore itemStore ) { FT_Memory memory = FT_FACE_MEMORY( face ); @@ -4470,7 +4557,7 @@ FT_LOCAL_DEF( void ) - tt_var_done_delta_set_index_map( TT_Face face, + tt_var_done_delta_set_index_map( FT_Face face, GX_DeltaSetIdxMap deltaSetIdxMap ) { FT_Memory memory = FT_FACE_MEMORY( face ); @@ -4490,10 +4577,11 @@ * Free the blend internal data structure. */ FT_LOCAL_DEF( void ) - tt_done_blend( TT_Face face ) + tt_done_blend( FT_Face face ) { + TT_Face ttface = (TT_Face)face; FT_Memory memory = FT_FACE_MEMORY( face ); - GX_Blend blend = face->blend; + GX_Blend blend = ttface->blend; if ( blend ) @@ -4565,7 +4653,7 @@ #else /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* ANSI C doesn't like empty source files */ - typedef int _tt_gxvar_dummy; + typedef int tt_gxvar_dummy_; #endif /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */ diff --git a/thirdparty/freetype/src/truetype/ttgxvar.h b/thirdparty/freetype/src/truetype/ttgxvar.h index 4fec980dcc..e3da6d1705 100644 --- a/thirdparty/freetype/src/truetype/ttgxvar.h +++ b/thirdparty/freetype/src/truetype/ttgxvar.h @@ -347,34 +347,41 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - TT_Set_MM_Blend( TT_Face face, + TT_Set_MM_Blend( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - TT_Get_MM_Blend( TT_Face face, + TT_Get_MM_Blend( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - TT_Set_Var_Design( TT_Face face, + TT_Set_Var_Design( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - TT_Get_MM_Var( TT_Face face, + TT_Get_MM_Var( FT_Face face, FT_MM_Var* *master ); FT_LOCAL( FT_Error ) - TT_Get_Var_Design( TT_Face face, + TT_Get_Var_Design( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - TT_Set_Named_Instance( TT_Face face, + TT_Set_Named_Instance( FT_Face face, FT_UInt instance_index ); FT_LOCAL( FT_Error ) + TT_Get_Default_Named_Instance( FT_Face face, + FT_UInt *instance_index ); + + FT_LOCAL( void ) + tt_construct_ps_name( FT_Face face ); + + FT_LOCAL( FT_Error ) tt_face_vary_cvt( TT_Face face, FT_Stream stream ); @@ -385,55 +392,54 @@ FT_BEGIN_HEADER FT_Vector* unrounded ); FT_LOCAL( FT_Error ) - tt_hadvance_adjust( TT_Face face, + tt_hadvance_adjust( FT_Face face, FT_UInt gindex, FT_Int *adelta ); FT_LOCAL( FT_Error ) - tt_vadvance_adjust( TT_Face face, + tt_vadvance_adjust( FT_Face face, FT_UInt gindex, FT_Int *adelta ); FT_LOCAL( void ) - tt_apply_mvar( TT_Face face ); - + tt_apply_mvar( FT_Face face ); FT_LOCAL( FT_Error ) - tt_var_load_item_variation_store( TT_Face face, + tt_var_load_item_variation_store( FT_Face face, FT_ULong offset, GX_ItemVarStore itemStore ); FT_LOCAL( FT_Error ) - tt_var_load_delta_set_index_mapping( TT_Face face, + tt_var_load_delta_set_index_mapping( FT_Face face, FT_ULong offset, GX_DeltaSetIdxMap map, GX_ItemVarStore itemStore, FT_ULong table_len ); FT_LOCAL( FT_ItemVarDelta ) - tt_var_get_item_delta( TT_Face face, + tt_var_get_item_delta( FT_Face face, GX_ItemVarStore itemStore, FT_UInt outerIndex, FT_UInt innerIndex ); FT_LOCAL( void ) - tt_var_done_item_variation_store( TT_Face face, + tt_var_done_item_variation_store( FT_Face face, GX_ItemVarStore itemStore ); FT_LOCAL( void ) - tt_var_done_delta_set_index_map( TT_Face face, + tt_var_done_delta_set_index_map( FT_Face face, GX_DeltaSetIdxMap deltaSetIdxMap ); FT_LOCAL( FT_Error ) - tt_get_var_blend( TT_Face face, + tt_get_var_blend( FT_Face face, FT_UInt *num_coords, FT_Fixed* *coords, FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ); FT_LOCAL( void ) - tt_done_blend( TT_Face face ); + tt_done_blend( FT_Face face ); #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ diff --git a/thirdparty/freetype/src/truetype/ttinterp.c b/thirdparty/freetype/src/truetype/ttinterp.c index 4fcfaa3e43..34c3e6c92a 100644 --- a/thirdparty/freetype/src/truetype/ttinterp.c +++ b/thirdparty/freetype/src/truetype/ttinterp.c @@ -278,57 +278,6 @@ /************************************************************************** * * @Function: - * Update_Max - * - * @Description: - * Checks the size of a buffer and reallocates it if necessary. - * - * @Input: - * memory :: - * A handle to the parent memory object. - * - * multiplier :: - * The size in bytes of each element in the buffer. - * - * new_max :: - * The new capacity (size) of the buffer. - * - * @InOut: - * size :: - * The address of the buffer's current size expressed - * in elements. - * - * buff :: - * The address of the buffer base pointer. - * - * @Return: - * FreeType error code. 0 means success. - */ - FT_LOCAL_DEF( FT_Error ) - Update_Max( FT_Memory memory, - FT_ULong* size, - FT_ULong multiplier, - void* _pbuff, - FT_ULong new_max ) - { - FT_Error error; - void** pbuff = (void**)_pbuff; - - - if ( *size < new_max ) - { - if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) - return error; - *size = new_max; - } - - return FT_Err_Ok; - } - - - /************************************************************************** - * - * @Function: * TT_Load_Context * * @Description: @@ -359,9 +308,9 @@ TT_Size size ) { FT_Int i; - FT_ULong tmp; TT_MaxProfile* maxp; FT_Error error; + FT_Memory memory = exec->memory; exec->face = face; @@ -406,25 +355,15 @@ /* XXX: We reserve a little more elements on the stack to deal safely */ /* with broken fonts like arialbs, courbs, timesbs, etc. */ - tmp = (FT_ULong)exec->stackSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_F26Dot6 ), - (void*)&exec->stack, - maxp->maxStackElements + 32 ); - exec->stackSize = (FT_Long)tmp; - if ( error ) + if ( FT_QRENEW_ARRAY( exec->stack, + exec->stackSize, + maxp->maxStackElements + 32 ) ) return error; + exec->stackSize = maxp->maxStackElements + 32; - tmp = (FT_ULong)exec->glyphSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void*)&exec->glyphIns, - maxp->maxSizeOfInstructions ); - exec->glyphSize = (FT_UInt)tmp; - if ( error ) - return error; + /* free previous glyph code range */ + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; exec->pts.n_points = 0; exec->pts.n_contours = 0; @@ -1530,14 +1469,16 @@ if ( exc->iniRange == tt_coderange_glyph && exc->cvt != exc->glyfCvt ) { - exc->error = Update_Max( exc->memory, - &exc->glyfCvtSize, - sizeof ( FT_Long ), - (void*)&exc->glyfCvt, - exc->cvtSize ); - if ( exc->error ) + FT_Memory memory = exc->memory; + FT_Error error; + + + FT_MEM_QRENEW_ARRAY( exc->glyfCvt, exc->glyfCvtSize, exc->cvtSize ); + exc->error = error; + if ( error ) return; + exc->glyfCvtSize = exc->cvtSize; FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize ); exc->cvt = exc->glyfCvt; } @@ -3117,18 +3058,18 @@ if ( exc->iniRange == tt_coderange_glyph && exc->storage != exc->glyfStorage ) { - FT_ULong tmp = (FT_ULong)exc->glyfStoreSize; + FT_Memory memory = exc->memory; + FT_Error error; - exc->error = Update_Max( exc->memory, - &tmp, - sizeof ( FT_Long ), - (void*)&exc->glyfStorage, - exc->storeSize ); - exc->glyfStoreSize = (FT_UShort)tmp; - if ( exc->error ) + FT_MEM_QRENEW_ARRAY( exc->glyfStorage, + exc->glyfStoreSize, + exc->storeSize ); + exc->error = error; + if ( error ) return; + exc->glyfStoreSize = exc->storeSize; FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize ); exc->storage = exc->glyfStorage; } @@ -3606,7 +3547,8 @@ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* arguments to opcodes are skipped by `SKIP_Code' */ - FT_Byte opcode_pattern[9][12] = { + FT_Byte opcode_pattern[9][12] = + { /* #0 inline delta function 1 */ { 0x4B, /* PPEM */ @@ -7380,14 +7322,6 @@ * GETINFO[]: GET INFOrmation * Opcode range: 0x88 * Stack: uint32 --> uint32 - * - * XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May - * 2015) not documented in the OpenType specification. - * - * Selector bit 11 is incorrectly described as bit 8, while the - * real meaning of bit 8 (vertical LCD subpixels) stays - * undocumented. The same mistake can be found in Greg Hitchcock's - * whitepaper. */ static void Ins_GETINFO( TT_ExecContext exc, @@ -7446,8 +7380,6 @@ * VARIATION GLYPH * Selector Bit: 3 * Return Bit(s): 10 - * - * XXX: UNDOCUMENTED! */ if ( (args[0] & 8 ) != 0 && exc->face->blend ) K |= 1 << 10; @@ -7739,20 +7671,23 @@ /* documentation is in ttinterp.h */ FT_EXPORT_DEF( FT_Error ) - TT_RunIns( TT_ExecContext exc ) + TT_RunIns( void* exec ) { + TT_ExecContext exc = (TT_ExecContext)exec; + FT_ULong ins_counter = 0; /* executed instructions counter */ FT_ULong num_twilight_points; FT_UShort i; #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - FT_Byte opcode_pattern[1][2] = { - /* #8 TypeMan Talk Align */ - { - 0x06, /* SPVTL */ - 0x7D, /* RDTG */ - }, - }; + FT_Byte opcode_pattern[1][2] = + { + /* #8 TypeMan Talk Align */ + { + 0x06, /* SPVTL */ + 0x7D, /* RDTG */ + }, + }; FT_UShort opcode_patterns = 1; FT_UShort opcode_pointer[1] = { 0 }; FT_UShort opcode_size[1] = { 1 }; @@ -7906,7 +7841,7 @@ /* a variable number of arguments */ /* it is the job of the application to `activate' GX handling, */ - /* this is, calling any of the GX API functions on the current */ + /* that is, calling any of the GX API functions on the current */ /* font to select a variation instance */ if ( exc->face->blend ) exc->new_top = exc->args + exc->face->blend->num_axis; @@ -8466,7 +8401,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT case 0x91: /* it is the job of the application to `activate' GX handling, */ - /* this is, calling any of the GX API functions on the current */ + /* that is, calling any of the GX API functions on the current */ /* font to select a variation instance */ if ( exc->face->blend ) Ins_GETVARIATION( exc, args ); @@ -8604,7 +8539,7 @@ #else /* !TT_USE_BYTECODE_INTERPRETER */ /* ANSI C doesn't like empty source files */ - typedef int _tt_interp_dummy; + typedef int tt_interp_dummy_; #endif /* !TT_USE_BYTECODE_INTERPRETER */ diff --git a/thirdparty/freetype/src/truetype/ttinterp.h b/thirdparty/freetype/src/truetype/ttinterp.h index c54c053b29..48d493af80 100644 --- a/thirdparty/freetype/src/truetype/ttinterp.h +++ b/thirdparty/freetype/src/truetype/ttinterp.h @@ -460,14 +460,6 @@ FT_BEGIN_HEADER FT_LOCAL( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ); - - - FT_LOCAL( FT_Error ) - Update_Max( FT_Memory memory, - FT_ULong* size, - FT_ULong multiplier, - void* _pbuff, - FT_ULong new_max ); #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -536,7 +528,7 @@ FT_BEGIN_HEADER * invoked by the TrueType debugger. */ FT_EXPORT( FT_Error ) - TT_RunIns( TT_ExecContext exec ); + TT_RunIns( void* exec ); FT_END_HEADER diff --git a/thirdparty/freetype/src/truetype/ttobjs.c b/thirdparty/freetype/src/truetype/ttobjs.c index 4a8873fd8c..958fa54d42 100644 --- a/thirdparty/freetype/src/truetype/ttobjs.c +++ b/thirdparty/freetype/src/truetype/ttobjs.c @@ -312,7 +312,8 @@ #define TRICK_SFNT_IDS_NUM_FACES 31 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] - [TRICK_SFNT_IDS_PER_FACE] = { + [TRICK_SFNT_IDS_PER_FACE] = + { #define TRICK_SFNT_ID_cvt 0 #define TRICK_SFNT_ID_fpgm 1 @@ -581,7 +582,7 @@ FT_Bool result = FALSE; TT_Face face = (TT_Face)ttface; - FT_UInt asize; + FT_ULong asize; FT_ULong i; FT_ULong glyph_index = 0; FT_UInt count = 0; @@ -589,7 +590,7 @@ for( i = 0; i < face->num_locations; i++ ) { - tt_face_get_location( face, i, &asize ); + tt_face_get_location( ttface, i, &asize ); if ( asize > 0 ) { count += 1; @@ -777,7 +778,6 @@ } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - { FT_UInt instance_index = (FT_UInt)face_index >> 16; @@ -785,14 +785,11 @@ if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && instance_index > 0 ) { - error = TT_Set_Named_Instance( face, instance_index ); + error = FT_Set_Named_Instance( ttface, instance_index ); if ( error ) goto Exit; - - tt_apply_mvar( face ); } } - #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* initialize standard glyph loading routines */ @@ -858,7 +855,7 @@ face->cvt_program_size = 0; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - tt_done_blend( face ); + tt_done_blend( ttface ); face->blend = NULL; #endif } @@ -1338,39 +1335,29 @@ /************************************************************************** * * @Function: - * tt_size_reset + * tt_size_reset_height * * @Description: - * Reset a TrueType size when resolutions and character dimensions - * have been changed. + * Recompute a TrueType size's ascender, descender, and height + * when resolutions and character dimensions have been changed. + * Used for variation fonts as an iterator function. * * @Input: - * size :: - * A handle to the target size object. - * - * only_height :: - * Only recompute ascender, descender, and height; - * this flag is used for variation fonts where - * `tt_size_reset' is used as an iterator function. + * ft_size :: + * A handle to the target TT_Size object. This function will be called + * through a `FT_Size_Reset_Func` pointer which takes `FT_Size`. This + * function must take `FT_Size` as a result. The passed `FT_Size` is + * expected to point to a `TT_Size`. */ FT_LOCAL_DEF( FT_Error ) - tt_size_reset( TT_Size size, - FT_Bool only_height ) + tt_size_reset_height( FT_Size ft_size ) { - TT_Face face; - FT_Size_Metrics* size_metrics; - - - face = (TT_Face)size->root.face; - - /* nothing to do for CFF2 */ - if ( face->is_cff2 ) - return FT_Err_Ok; + TT_Size size = (TT_Size)ft_size; + TT_Face face = (TT_Face)size->root.face; + FT_Size_Metrics* size_metrics = &size->hinted_metrics; size->ttmetrics.valid = FALSE; - size_metrics = &size->hinted_metrics; - /* copy the result from base layer */ *size_metrics = size->root.metrics; @@ -1397,12 +1384,34 @@ size->ttmetrics.valid = TRUE; - if ( only_height ) - { - /* we must not recompute the scaling values here since */ - /* `tt_size_reset' was already called (with only_height = 0) */ - return FT_Err_Ok; - } + return FT_Err_Ok; + } + + + /************************************************************************** + * + * @Function: + * tt_size_reset + * + * @Description: + * Reset a TrueType size when resolutions and character dimensions + * have been changed. + * + * @Input: + * size :: + * A handle to the target size object. + */ + FT_LOCAL_DEF( FT_Error ) + tt_size_reset( TT_Size size ) + { + FT_Error error; + TT_Face face = (TT_Face)size->root.face; + FT_Size_Metrics* size_metrics = &size->hinted_metrics; + + + error = tt_size_reset_height( (FT_Size)size ); + if ( error ) + return error; if ( face->header.Flags & 8 ) { diff --git a/thirdparty/freetype/src/truetype/ttobjs.h b/thirdparty/freetype/src/truetype/ttobjs.h index bc6fbe7f19..d1834c046f 100644 --- a/thirdparty/freetype/src/truetype/ttobjs.h +++ b/thirdparty/freetype/src/truetype/ttobjs.h @@ -391,8 +391,10 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ FT_LOCAL( FT_Error ) - tt_size_reset( TT_Size size, - FT_Bool only_height ); + tt_size_reset_height( FT_Size size ); + + FT_LOCAL( FT_Error ) + tt_size_reset( TT_Size size ); /************************************************************************** diff --git a/thirdparty/freetype/src/truetype/ttpload.c b/thirdparty/freetype/src/truetype/ttpload.c index e08bf309e3..54a64c7b46 100644 --- a/thirdparty/freetype/src/truetype/ttpload.c +++ b/thirdparty/freetype/src/truetype/ttpload.c @@ -180,10 +180,11 @@ FT_LOCAL_DEF( FT_ULong ) - tt_face_get_location( TT_Face face, - FT_UInt gindex, - FT_UInt *asize ) + tt_face_get_location( FT_Face face, /* TT_Face */ + FT_UInt gindex, + FT_ULong *asize ) { + TT_Face ttface = (TT_Face)face; FT_ULong pos1, pos2; FT_Byte* p; FT_Byte* p_limit; @@ -191,12 +192,12 @@ pos1 = pos2 = 0; - if ( gindex < face->num_locations ) + if ( gindex < ttface->num_locations ) { - if ( face->header.Index_To_Loc_Format != 0 ) + if ( ttface->header.Index_To_Loc_Format != 0 ) { - p = face->glyph_locations + gindex * 4; - p_limit = face->glyph_locations + face->num_locations * 4; + p = ttface->glyph_locations + gindex * 4; + p_limit = ttface->glyph_locations + ttface->num_locations * 4; pos1 = FT_NEXT_ULONG( p ); pos2 = pos1; @@ -206,8 +207,8 @@ } else { - p = face->glyph_locations + gindex * 2; - p_limit = face->glyph_locations + face->num_locations * 2; + p = ttface->glyph_locations + gindex * 2; + p_limit = ttface->glyph_locations + ttface->num_locations * 2; pos1 = FT_NEXT_USHORT( p ); pos2 = pos1; @@ -221,30 +222,30 @@ } /* Check broken location data. */ - if ( pos1 > face->glyf_len ) + if ( pos1 > ttface->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" " too large offset (0x%08lx) found for glyph index %d,\n", pos1, gindex )); FT_TRACE1(( " " " exceeding the end of `glyf' table (0x%08lx)\n", - face->glyf_len )); + ttface->glyf_len )); *asize = 0; return 0; } - if ( pos2 > face->glyf_len ) + if ( pos2 > ttface->glyf_len ) { /* We try to sanitize the last `loca' entry. */ - if ( gindex == face->num_locations - 2 ) + if ( gindex == ttface->num_locations - 2 ) { FT_TRACE1(( "tt_face_get_location:" " too large size (%ld bytes) found for glyph index %d,\n", pos2 - pos1, gindex )); FT_TRACE1(( " " " truncating at the end of `glyf' table to %ld bytes\n", - face->glyf_len - pos1 )); - pos2 = face->glyf_len; + ttface->glyf_len - pos1 )); + pos2 = ttface->glyf_len; } else { @@ -253,7 +254,7 @@ pos2, gindex + 1 )); FT_TRACE1(( " " " exceeding the end of `glyf' table (0x%08lx)\n", - face->glyf_len )); + ttface->glyf_len )); *asize = 0; return 0; } @@ -268,9 +269,9 @@ /* We get (intentionally) a wrong, non-zero result in case the */ /* `glyf' table is missing. */ if ( pos2 >= pos1 ) - *asize = (FT_UInt)( pos2 - pos1 ); + *asize = (FT_ULong)( pos2 - pos1 ); else - *asize = (FT_UInt)( face->glyf_len - pos1 ); + *asize = (FT_ULong)( ttface->glyf_len - pos1 ); return pos1; } diff --git a/thirdparty/freetype/src/truetype/ttpload.h b/thirdparty/freetype/src/truetype/ttpload.h index 939e02fe4f..ed229fa461 100644 --- a/thirdparty/freetype/src/truetype/ttpload.h +++ b/thirdparty/freetype/src/truetype/ttpload.h @@ -31,9 +31,9 @@ FT_BEGIN_HEADER FT_Stream stream ); FT_LOCAL( FT_ULong ) - tt_face_get_location( TT_Face face, - FT_UInt gindex, - FT_UInt *asize ); + tt_face_get_location( FT_Face face, + FT_UInt gindex, + FT_ULong *asize ); FT_LOCAL( void ) tt_face_done_loca( TT_Face face ); diff --git a/thirdparty/freetype/src/truetype/ttsubpix.c b/thirdparty/freetype/src/truetype/ttsubpix.c index d811beef0d..aed4a1a274 100644 --- a/thirdparty/freetype/src/truetype/ttsubpix.c +++ b/thirdparty/freetype/src/truetype/ttsubpix.c @@ -1004,7 +1004,7 @@ /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY) */ /* ANSI C doesn't like empty source files */ - typedef int _tt_subpix_dummy; + typedef int tt_subpix_dummy_; #endif /* !(TT_USE_BYTECODE_INTERPRETER && */ /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY) */ diff --git a/thirdparty/freetype/src/type1/t1afm.c b/thirdparty/freetype/src/type1/t1afm.c index 787aa92c98..d9b9398b01 100644 --- a/thirdparty/freetype/src/type1/t1afm.c +++ b/thirdparty/freetype/src/type1/t1afm.c @@ -299,7 +299,7 @@ /* ascender and descender are optional and could both be zero */ /* check if values are meaningful before overriding defaults */ if ( fi->Ascender > fi->Descender ) - { + { /* no `U' suffix here to 0x8000! */ t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000 ) >> 16 ); t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 ); @@ -405,7 +405,7 @@ #else /* T1_CONFIG_OPTION_NO_AFM */ /* ANSI C doesn't like empty source files */ - typedef int _t1_afm_dummy; + typedef int t1_afm_dummy_; #endif /* T1_CONFIG_OPTION_NO_AFM */ diff --git a/thirdparty/freetype/src/type1/t1driver.c b/thirdparty/freetype/src/type1/t1driver.c index ded3b264e8..a4cdf372a9 100644 --- a/thirdparty/freetype/src/type1/t1driver.c +++ b/thirdparty/freetype/src/type1/t1driver.c @@ -56,28 +56,32 @@ * */ - static FT_Error - t1_get_glyph_name( T1_Face face, + FT_CALLBACK_DEF( FT_Error ) + t1_get_glyph_name( FT_Face face, /* T1_Face */ FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) { - FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); + T1_Face t1face = (T1_Face)face; + + + FT_STRCPYN( buffer, t1face->type1.glyph_names[glyph_index], buffer_max ); return FT_Err_Ok; } - static FT_UInt - t1_get_name_index( T1_Face face, + FT_CALLBACK_DEF( FT_UInt ) + t1_get_name_index( FT_Face face, /* T1_Face */ const FT_String* glyph_name ) { - FT_Int i; + T1_Face t1face = (T1_Face)face; + FT_Int i; - for ( i = 0; i < face->type1.num_glyphs; i++ ) + for ( i = 0; i < t1face->type1.num_glyphs; i++ ) { - FT_String* gname = face->type1.glyph_names[i]; + FT_String* gname = t1face->type1.glyph_names[i]; if ( !ft_strcmp( glyph_name, gname ) ) @@ -90,8 +94,8 @@ static const FT_Service_GlyphDictRec t1_service_glyph_dict = { - (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, /* get_name */ - (FT_GlyphDict_NameIndexFunc)t1_get_name_index /* name_index */ + t1_get_glyph_name, /* FT_GlyphDict_GetNameFunc get_name */ + t1_get_name_index /* FT_GlyphDict_NameIndexFunc name_index */ }; @@ -101,9 +105,12 @@ */ static const char* - t1_get_ps_name( T1_Face face ) + t1_get_ps_name( FT_Face face ) /* T1_Face */ { - return (const char*) face->type1.font_name; + T1_Face t1face = (T1_Face)face; + + + return (const char*) t1face->type1.font_name; } @@ -121,30 +128,28 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = { - (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ - (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ - (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */ - (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ - (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */ - (FT_Set_MM_WeightVector_Func) - T1_Set_MM_WeightVector, /* set_mm_weightvector */ - (FT_Get_MM_WeightVector_Func) - T1_Get_MM_WeightVector, /* get_mm_weightvector */ - (FT_Var_Load_Delta_Set_Idx_Map_Func) - NULL, /* load_delta_set_idx_map */ - (FT_Var_Load_Item_Var_Store_Func) - NULL, /* load_item_variation_store */ - (FT_Var_Get_Item_Delta_Func) - NULL, /* get_item_delta */ - (FT_Var_Done_Item_Var_Store_Func) - NULL, /* done_item_variation_store */ - (FT_Var_Done_Delta_Set_Idx_Map_Func) - NULL, /* done_delta_set_index_map */ - (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ - (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ + T1_Get_Multi_Master, /* FT_Get_MM_Func get_mm */ + T1_Set_MM_Design, /* FT_Set_MM_Design_Func set_mm_design */ + T1_Set_MM_Blend, /* FT_Set_MM_Blend_Func set_mm_blend */ + T1_Get_MM_Blend, /* FT_Get_MM_Blend_Func get_mm_blend */ + T1_Get_MM_Var, /* FT_Get_MM_Var_Func get_mm_var */ + T1_Set_Var_Design, /* FT_Set_Var_Design_Func set_var_design */ + T1_Get_Var_Design, /* FT_Get_Var_Design_Func get_var_design */ + T1_Reset_MM_Blend, /* FT_Set_Named_Instance_Func set_named_instance */ + NULL, /* FT_Get_Default_Named_Instance_Func get_default_named_instance */ + T1_Set_MM_WeightVector, + /* FT_Set_MM_WeightVector_Func set_mm_weightvector */ + T1_Get_MM_WeightVector, + /* FT_Get_MM_WeightVector_Func get_mm_weightvector */ + + NULL, /* FT_Construct_PS_Name_Func construct_ps_name */ + NULL, /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map */ + NULL, /* FT_Var_Load_Item_Var_Store_Func load_item_variation_store */ + NULL, /* FT_Var_Get_Item_Delta_Func get_item_delta */ + NULL, /* FT_Var_Done_Item_Var_Store_Func done_item_variation_store */ + NULL, /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map */ + NULL, /* FT_Get_Var_Blend_Func get_var_blend */ + T1_Done_Blend /* FT_Done_Blend_Func done_blend */ }; #endif @@ -632,11 +637,11 @@ static const FT_Service_PsInfoRec t1_service_ps_info = { - (PS_GetFontInfoFunc) t1_ps_get_font_info, /* ps_get_font_info */ - (PS_GetFontExtraFunc) t1_ps_get_font_extra, /* ps_get_font_extra */ - (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, /* ps_has_glyph_names */ - (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */ - (PS_GetFontValueFunc) t1_ps_get_font_value, /* ps_get_font_value */ + t1_ps_get_font_info, /* PS_GetFontInfoFunc ps_get_font_info */ + t1_ps_get_font_extra, /* PS_GetFontExtraFunc ps_get_font_extra */ + t1_ps_has_glyph_names, /* PS_HasGlyphNamesFunc ps_has_glyph_names */ + t1_ps_get_font_private, /* PS_GetFontPrivateFunc ps_get_font_private */ + t1_ps_get_font_value, /* PS_GetFontValueFunc ps_get_font_value */ }; @@ -656,9 +661,9 @@ FT_DEFINE_SERVICE_PROPERTIESREC( t1_service_properties, - (FT_Properties_SetFunc)ps_property_set, /* set_property */ - (FT_Properties_GetFunc)ps_property_get ) /* get_property */ - + ps_property_set, /* FT_Properties_SetFunc set_property */ + ps_property_get /* FT_Properties_GetFunc get_property */ + ) /* * SERVICE LIST diff --git a/thirdparty/freetype/src/type1/t1load.c b/thirdparty/freetype/src/type1/t1load.c index 5a1afd8d9f..b292a3cc0e 100644 --- a/thirdparty/freetype/src/type1/t1load.c +++ b/thirdparty/freetype/src/type1/t1load.c @@ -73,7 +73,8 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL -#define IS_INCREMENTAL FT_BOOL( face->root.internal->incremental_interface ) +#define IS_INCREMENTAL \ + FT_BOOL( FT_FACE( face )->internal->incremental_interface ) #else #define IS_INCREMENTAL 0 #endif @@ -174,10 +175,11 @@ FT_LOCAL_DEF( FT_Error ) - T1_Get_Multi_Master( T1_Face face, + T1_Get_Multi_Master( FT_Face face, /* T1_Face */ FT_Multi_Master* master ) { - PS_Blend blend = face->blend; + T1_Face t1face = (T1_Face)face; + PS_Blend blend = t1face->blend; FT_UInt n; FT_Error error; @@ -225,11 +227,12 @@ for ( j = 1; j < axismap->num_points; j++ ) { if ( ncv <= axismap->blend_points[j] ) - return INT_TO_FIXED( axismap->design_points[j - 1] ) + - ( axismap->design_points[j] - axismap->design_points[j - 1] ) * - FT_DivFix( ncv - axismap->blend_points[j - 1], - axismap->blend_points[j] - - axismap->blend_points[j - 1] ); + return INT_TO_FIXED( axismap->design_points[j - 1] + + FT_MulDiv( ncv - axismap->blend_points[j - 1], + axismap->design_points[j] - + axismap->design_points[j - 1], + axismap->blend_points[j] - + axismap->blend_points[j - 1] ) ); } return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] ); @@ -284,16 +287,17 @@ * arguments needed by the GX var distortable fonts. */ FT_LOCAL_DEF( FT_Error ) - T1_Get_MM_Var( T1_Face face, + T1_Get_MM_Var( FT_Face face, /* T1_Face */ FT_MM_Var* *master ) { - FT_Memory memory = face->root.memory; - FT_MM_Var *mmvar = NULL; + T1_Face t1face = (T1_Face)face; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_MM_Var *mmvar = NULL; FT_Multi_Master mmaster; FT_Error error; FT_UInt i; FT_Fixed axiscoords[T1_MAX_MM_AXIS]; - PS_Blend blend = face->blend; + PS_Blend blend = t1face->blend; FT_UShort* axis_flags; FT_Offset mmvar_size; @@ -319,9 +323,9 @@ sizeof ( FT_UShort ) ); axis_size = mmaster.num_axis * sizeof ( FT_Var_Axis ); - if ( FT_ALLOC( mmvar, mmvar_size + - axis_flags_size + - axis_size ) ) + if ( FT_QALLOC( mmvar, mmvar_size + + axis_flags_size + + axis_size ) ) goto Exit; mmvar->num_axis = mmaster.num_axis; @@ -332,8 +336,7 @@ /* to make `FT_Get_Var_Axis_Flags' work: the function expects that the */ /* values directly follow the data of `FT_MM_Var' */ axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size ); - for ( i = 0; i < mmaster.num_axis; i++ ) - axis_flags[i] = 0; + FT_ARRAY_ZERO( axis_flags, mmaster.num_axis ); mmvar->axis = (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size ); mmvar->namedstyle = NULL; @@ -438,32 +441,21 @@ FT_LOCAL_DEF( FT_Error ) - T1_Set_MM_Blend( T1_Face face, + T1_Set_MM_Blend( FT_Face face, /* T1_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error; - - - error = t1_set_mm_blend( face, num_coords, coords ); - if ( error ) - return error; - - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - - return FT_Err_Ok; + return t1_set_mm_blend( (T1_Face)face, num_coords, coords ); } FT_LOCAL_DEF( FT_Error ) - T1_Get_MM_Blend( T1_Face face, + T1_Get_MM_Blend( FT_Face face, /* T1_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - PS_Blend blend = face->blend; + T1_Face t1face = (T1_Face)face; + PS_Blend blend = t1face->blend; FT_Fixed axiscoords[4]; FT_UInt i, nc; @@ -494,11 +486,12 @@ FT_LOCAL_DEF( FT_Error ) - T1_Set_MM_WeightVector( T1_Face face, + T1_Set_MM_WeightVector( FT_Face face, /* T1_Face */ FT_UInt len, FT_Fixed* weightvector ) { - PS_Blend blend = face->blend; + T1_Face t1face = (T1_Face)face; + PS_Blend blend = t1face->blend; FT_UInt i, n; @@ -522,11 +515,6 @@ for ( ; i < blend->num_designs; i++ ) blend->weight_vector[i] = (FT_Fixed)0; - - if ( len ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; } return FT_Err_Ok; @@ -534,11 +522,12 @@ FT_LOCAL_DEF( FT_Error ) - T1_Get_MM_WeightVector( T1_Face face, + T1_Get_MM_WeightVector( FT_Face face, /* T1_Face */ FT_UInt* len, FT_Fixed* weightvector ) { - PS_Blend blend = face->blend; + T1_Face t1face = (T1_Face)face; + PS_Blend blend = t1face->blend; FT_UInt i; @@ -563,12 +552,13 @@ FT_LOCAL_DEF( FT_Error ) - T1_Set_MM_Design( T1_Face face, + T1_Set_MM_Design( FT_Face face, /* T1_Face */ FT_UInt num_coords, FT_Long* coords ) { + T1_Face t1face = (T1_Face)face; FT_Error error; - PS_Blend blend = face->blend; + PS_Blend blend = t1face->blend; FT_UInt n; FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; @@ -634,15 +624,10 @@ final_blends[n] = the_blend; } - error = t1_set_mm_blend( face, blend->num_axis, final_blends ); + error = t1_set_mm_blend( t1face, blend->num_axis, final_blends ); if ( error ) return error; - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - return FT_Err_Ok; } @@ -650,7 +635,7 @@ /* MM fonts don't have named instances, so only the design is reset */ FT_LOCAL_DEF( FT_Error ) - T1_Reset_MM_Blend( T1_Face face, + T1_Reset_MM_Blend( FT_Face face, FT_UInt instance_index ) { FT_UNUSED( instance_index ); @@ -665,7 +650,7 @@ * arguments needed by the GX var distortable fonts. */ FT_LOCAL_DEF( FT_Error ) - T1_Set_Var_Design( T1_Face face, + T1_Set_Var_Design( FT_Face face, /* T1_Face */ FT_UInt num_coords, FT_Fixed* coords ) { @@ -684,11 +669,12 @@ FT_LOCAL_DEF( FT_Error ) - T1_Get_Var_Design( T1_Face face, + T1_Get_Var_Design( FT_Face face, /* T1_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - PS_Blend blend = face->blend; + T1_Face t1face = (T1_Face)face; + PS_Blend blend = t1face->blend; FT_Fixed axiscoords[4]; FT_UInt i, nc; @@ -720,10 +706,11 @@ FT_LOCAL_DEF( void ) - T1_Done_Blend( T1_Face face ) + T1_Done_Blend( FT_Face face ) /* T1_Face */ { - FT_Memory memory = face->root.memory; - PS_Blend blend = face->blend; + T1_Face t1face = (T1_Face)face; + FT_Memory memory = FT_FACE_MEMORY( face ); + PS_Blend blend = t1face->blend; if ( blend ) @@ -768,20 +755,22 @@ dmap->num_points = 0; } - FT_FREE( face->blend ); + FT_FREE( t1face->blend ); } } static void - parse_blend_axis_types( T1_Face face, - T1_Loader loader ) + parse_blend_axis_types( FT_Face face, /* T1_Face */ + void* loader_ ) { + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; FT_Int n, num_axis; - FT_Error error = FT_Err_Ok; + FT_Error error = FT_Err_Ok; PS_Blend blend; - FT_Memory memory; + FT_Memory memory = FT_FACE_MEMORY( face ); /* take an array of objects */ @@ -801,14 +790,13 @@ } /* allocate blend if necessary */ - error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); + error = t1_allocate_blend( t1face, 0, (FT_UInt)num_axis ); if ( error ) goto Exit; FT_TRACE4(( " [" )); - blend = face->blend; - memory = face->root.memory; + blend = t1face->blend; /* each token is an immediate containing the name of the axis */ for ( n = 0; n < num_axis; n++ ) @@ -856,14 +844,16 @@ static void - parse_blend_design_positions( T1_Face face, - T1_Loader loader ) + parse_blend_design_positions( FT_Face face, /* T1_Face */ + void* loader_ ) { + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; FT_Int num_designs; FT_Int num_axis = 0; /* make compiler happy */ T1_Parser parser = &loader->parser; - FT_Memory memory = face->root.memory; + FT_Memory memory = FT_FACE_MEMORY( face ); FT_Error error = FT_Err_Ok; FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; @@ -921,7 +911,7 @@ } num_axis = n_axis; - error = t1_allocate_blend( face, + error = t1_allocate_blend( t1face, (FT_UInt)num_designs, (FT_UInt)num_axis ); if ( error ) @@ -962,7 +952,7 @@ loader->parser.root.limit = old_limit; /* a valid BlendDesignPosition has been parsed */ - blend = face->blend; + blend = t1face->blend; if ( blend->design_pos[0] ) FT_FREE( blend->design_pos[0] ); @@ -980,9 +970,11 @@ static void - parse_blend_design_map( T1_Face face, - T1_Loader loader ) + parse_blend_design_map( FT_Face face, /* T1_Face */ + void* loader_ ) { + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; FT_Error error = FT_Err_Ok; T1_Parser parser = &loader->parser; PS_Blend blend; @@ -990,7 +982,7 @@ FT_Int n, num_axis; FT_Byte* old_cursor; FT_Byte* old_limit; - FT_Memory memory = face->root.memory; + FT_Memory memory = FT_FACE_MEMORY( face ); T1_ToTokenArray( parser, axis_tokens, @@ -1011,10 +1003,10 @@ old_cursor = parser->root.cursor; old_limit = parser->root.limit; - error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); + error = t1_allocate_blend( t1face, 0, (FT_UInt)num_axis ); if ( error ) goto Exit; - blend = face->blend; + blend = t1face->blend; FT_TRACE4(( " [" )); @@ -1089,15 +1081,17 @@ static void - parse_weight_vector( T1_Face face, - T1_Loader loader ) + parse_weight_vector( FT_Face face, /* T1_Face */ + void* loader_ ) { + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; FT_Int num_designs; FT_Error error = FT_Err_Ok; - FT_Memory memory = face->root.memory; + FT_Memory memory = FT_FACE_MEMORY( face ); T1_Parser parser = &loader->parser; - PS_Blend blend = face->blend; + PS_Blend blend = t1face->blend; T1_Token token; FT_Int n; FT_Byte* old_cursor; @@ -1122,10 +1116,10 @@ if ( !blend || !blend->num_designs ) { - error = t1_allocate_blend( face, (FT_UInt)num_designs, 0 ); + error = t1_allocate_blend( t1face, (FT_UInt)num_designs, 0 ); if ( error ) goto Exit; - blend = face->blend; + blend = t1face->blend; } else if ( blend->num_designs != (FT_UInt)num_designs ) { @@ -1173,11 +1167,15 @@ /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def */ /* we're only interested in the number of array elements */ static void - parse_buildchar( T1_Face face, - T1_Loader loader ) + parse_buildchar( FT_Face face, /* T1_Face */ + void* loader_ ) { - face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser, - 0, NULL, 0 ); + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; + + + t1face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser, + 0, NULL, 0 ); #ifdef FT_DEBUG_LEVEL_TRACE { @@ -1185,7 +1183,7 @@ FT_TRACE4(( " [" )); - for ( i = 0; i < face->len_buildchar; i++ ) + for ( i = 0; i < t1face->len_buildchar; i++ ) FT_TRACE4(( " 0" )); FT_TRACE4(( "]\n" )); @@ -1335,9 +1333,10 @@ static void - parse_private( T1_Face face, - T1_Loader loader ) + parse_private( FT_Face face, + void* loader_ ) { + T1_Loader loader = (T1_Loader)loader_; FT_UNUSED( face ); loader->keywords_encountered |= T1_PRIVATE; @@ -1401,13 +1400,14 @@ /* and `/CharStrings' dictionaries. */ static void - t1_parse_font_matrix( T1_Face face, - T1_Loader loader ) + t1_parse_font_matrix( FT_Face face, /* T1_Face */ + void* loader_ ) { + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; T1_Parser parser = &loader->parser; - FT_Matrix* matrix = &face->type1.font_matrix; - FT_Vector* offset = &face->type1.font_offset; - FT_Face root = (FT_Face)&face->root; + FT_Matrix* matrix = &t1face->type1.font_matrix; + FT_Vector* offset = &t1face->type1.font_offset; FT_Fixed temp[6]; FT_Fixed temp_scale; FT_Int result; @@ -1443,7 +1443,7 @@ if ( temp_scale != 0x10000L ) { /* set units per EM based on FontMatrix values */ - root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); + face->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); temp[0] = FT_DivFix( temp[0], temp_scale ); temp[1] = FT_DivFix( temp[1], temp_scale ); @@ -1471,14 +1471,16 @@ static void - parse_encoding( T1_Face face, - T1_Loader loader ) + parse_encoding( FT_Face face, /* T1_Face */ + void* loader_ ) { + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; T1_Parser parser = &loader->parser; FT_Byte* cur; FT_Byte* limit = parser->root.limit; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)t1face->psaux; T1_Skip_Spaces( parser ); @@ -1494,7 +1496,7 @@ /* and we must load it now */ if ( ft_isdigit( *cur ) || *cur == '[' ) { - T1_Encoding encode = &face->type1.encoding; + T1_Encoding encode = &t1face->type1.encoding; FT_Int count, array_size, n; PS_Table char_table = &loader->encoding_table; FT_Memory memory = parser->root.memory; @@ -1676,7 +1678,7 @@ FT_TRACE4(( "]\n" )); #endif - face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + t1face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; parser->root.cursor = cur; } @@ -1687,21 +1689,21 @@ if ( cur + 17 < limit && ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) { - face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + t1face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; FT_TRACE4(( " StandardEncoding\n" )); } else if ( cur + 15 < limit && ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) { - face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + t1face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; FT_TRACE4(( " ExpertEncoding\n" )); } else if ( cur + 18 < limit && ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) { - face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + t1face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; FT_TRACE4(( " ISOLatin1Encoding\n" )); } @@ -1715,9 +1717,11 @@ static void - parse_subrs( T1_Face face, - T1_Loader loader ) + parse_subrs( FT_Face face, /* T1_Face */ + void* loader_ ) { + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; T1_Parser parser = &loader->parser; PS_Table table = &loader->subrs; FT_Memory memory = parser->root.memory; @@ -1725,7 +1729,7 @@ FT_Int num_subrs; FT_UInt count; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)t1face->psaux; T1_Skip_Spaces( parser ); @@ -1857,7 +1861,7 @@ /* */ /* thanks to Tom Kacvinsky for pointing this out */ /* */ - if ( face->type1.private_dict.lenIV >= 0 ) + if ( t1face->type1.private_dict.lenIV >= 0 ) { FT_Byte* temp = NULL; @@ -1865,7 +1869,7 @@ /* some fonts define empty subr records -- this is not totally */ /* compliant to the specification (which says they should at */ /* least contain a `return'), but we support them anyway */ - if ( size < (FT_ULong)face->type1.private_dict.lenIV ) + if ( size < (FT_ULong)t1face->type1.private_dict.lenIV ) { error = FT_THROW( Invalid_File_Format ); goto Fail; @@ -1876,9 +1880,11 @@ goto Fail; FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); - size -= (FT_ULong)face->type1.private_dict.lenIV; - error = T1_Add_Table( table, (FT_Int)idx, - temp + face->type1.private_dict.lenIV, size ); + size -= (FT_ULong)t1face->type1.private_dict.lenIV; + error = T1_Add_Table( table, + (FT_Int)idx, + temp + t1face->type1.private_dict.lenIV, + size ); FT_FREE( temp ); } else @@ -1910,9 +1916,11 @@ static void - parse_charstrings( T1_Face face, - T1_Loader loader ) + parse_charstrings( FT_Face face, /* T1_Face */ + void* loader_ ) { + T1_Face t1face = (T1_Face)face; + T1_Loader loader = (T1_Loader)loader_; T1_Parser parser = &loader->parser; PS_Table code_table = &loader->charstrings; PS_Table name_table = &loader->glyph_names; @@ -1920,7 +1928,7 @@ FT_Memory memory = parser->root.memory; FT_Error error; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)t1face->psaux; FT_Byte* cur = parser->root.cursor; FT_Byte* limit = parser->root.limit; @@ -2069,13 +2077,13 @@ notdef_found = 1; } - if ( face->type1.private_dict.lenIV >= 0 && + if ( t1face->type1.private_dict.lenIV >= 0 && n < num_glyphs + TABLE_EXTEND ) { FT_Byte* temp = NULL; - if ( size <= (FT_ULong)face->type1.private_dict.lenIV ) + if ( size <= (FT_ULong)t1face->type1.private_dict.lenIV ) { error = FT_THROW( Invalid_File_Format ); goto Fail; @@ -2086,9 +2094,11 @@ goto Fail; FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); - size -= (FT_ULong)face->type1.private_dict.lenIV; - error = T1_Add_Table( code_table, n, - temp + face->type1.private_dict.lenIV, size ); + size -= (FT_ULong)t1face->type1.private_dict.lenIV; + error = T1_Add_Table( code_table, + n, + temp + t1face->type1.private_dict.lenIV, + size ); FT_FREE( temp ); } else @@ -2570,7 +2580,7 @@ { FT_ERROR(( "T1_Open_Face:" " number-of-designs != 2 ^^ number-of-axes\n" )); - T1_Done_Blend( face ); + T1_Done_Blend( FT_FACE( face ) ); } if ( face->blend && @@ -2590,15 +2600,15 @@ /* font as a normal PS font */ if ( face->blend && ( !face->blend->num_designs || !face->blend->num_axis ) ) - T1_Done_Blend( face ); + T1_Done_Blend( FT_FACE( face ) ); /* the font may have no valid WeightVector */ if ( face->blend && !face->blend->weight_vector ) - T1_Done_Blend( face ); + T1_Done_Blend( FT_FACE( face ) ); /* the font may have no valid BlendDesignPositions */ if ( face->blend && !face->blend->design_pos[0] ) - T1_Done_Blend( face ); + T1_Done_Blend( FT_FACE( face ) ); /* the font may have no valid BlendDesignMap */ if ( face->blend ) @@ -2609,7 +2619,7 @@ for ( i = 0; i < face->blend->num_axis; i++ ) if ( !face->blend->design_map[i].num_points ) { - T1_Done_Blend( face ); + T1_Done_Blend( FT_FACE( face ) ); break; } } diff --git a/thirdparty/freetype/src/type1/t1load.h b/thirdparty/freetype/src/type1/t1load.h index f8511cccf6..d8c9d2d8ab 100644 --- a/thirdparty/freetype/src/type1/t1load.h +++ b/thirdparty/freetype/src/type1/t1load.h @@ -66,52 +66,52 @@ FT_BEGIN_HEADER #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT FT_LOCAL( FT_Error ) - T1_Get_Multi_Master( T1_Face face, + T1_Get_Multi_Master( FT_Face face, FT_Multi_Master* master ); FT_LOCAL( FT_Error ) - T1_Get_MM_Var( T1_Face face, + T1_Get_MM_Var( FT_Face face, FT_MM_Var* *master ); FT_LOCAL( FT_Error ) - T1_Set_MM_Blend( T1_Face face, + T1_Set_MM_Blend( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - T1_Get_MM_Blend( T1_Face face, + T1_Get_MM_Blend( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - T1_Set_MM_Design( T1_Face face, + T1_Set_MM_Design( FT_Face face, FT_UInt num_coords, FT_Long* coords ); FT_LOCAL( FT_Error ) - T1_Reset_MM_Blend( T1_Face face, + T1_Reset_MM_Blend( FT_Face face, FT_UInt instance_index ); FT_LOCAL( FT_Error ) - T1_Get_Var_Design( T1_Face face, + T1_Get_Var_Design( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - T1_Set_Var_Design( T1_Face face, + T1_Set_Var_Design( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( void ) - T1_Done_Blend( T1_Face face ); + T1_Done_Blend( FT_Face face ); FT_LOCAL( FT_Error ) - T1_Set_MM_WeightVector( T1_Face face, + T1_Set_MM_WeightVector( FT_Face face, FT_UInt len, FT_Fixed* weightvector ); FT_LOCAL( FT_Error ) - T1_Get_MM_WeightVector( T1_Face face, + T1_Get_MM_WeightVector( FT_Face face, FT_UInt* len, FT_Fixed* weightvector ); diff --git a/thirdparty/freetype/src/type1/t1objs.c b/thirdparty/freetype/src/type1/t1objs.c index 1bb2f15f3a..69e4fd5065 100644 --- a/thirdparty/freetype/src/type1/t1objs.c +++ b/thirdparty/freetype/src/type1/t1objs.c @@ -167,8 +167,7 @@ FT_Module module; - module = FT_Get_Module( slot->face->driver->root.library, - "pshinter" ); + module = FT_Get_Module( slot->library, "pshinter" ); if ( module ) { T1_Hints_Funcs funcs; @@ -227,7 +226,7 @@ face->len_buildchar = 0; } - T1_Done_Blend( face ); + T1_Done_Blend( t1face ); face->blend = NULL; #endif @@ -290,7 +289,8 @@ * * @Input: * stream :: - * input stream where to load font data. + * Dummy argument for compatibility with the `FT_Face_InitFunc` API. + * Ignored. The stream should be passed through `face->root.stream`. * * face_index :: * The index of the font face in the resource. diff --git a/thirdparty/freetype/src/type42/t42drivr.c b/thirdparty/freetype/src/type42/t42drivr.c index ce1528e5db..ee5fd44a9f 100644 --- a/thirdparty/freetype/src/type42/t42drivr.c +++ b/thirdparty/freetype/src/type42/t42drivr.c @@ -56,33 +56,41 @@ * */ - static FT_Error - t42_get_glyph_name( T42_Face face, + FT_CALLBACK_DEF( FT_Error ) + t42_get_glyph_name( FT_Face face, /* T42_Face */ FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) { - FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); + T42_Face t42face = (T42_Face)face; + + + FT_STRCPYN( buffer, + t42face->type1.glyph_names[glyph_index], + buffer_max ); return FT_Err_Ok; } - static FT_UInt - t42_get_name_index( T42_Face face, + FT_CALLBACK_DEF( FT_UInt ) + t42_get_name_index( FT_Face face, /* T42_Face */ const FT_String* glyph_name ) { - FT_Int i; + T42_Face t42face = (T42_Face)face; + FT_Int i; - for ( i = 0; i < face->type1.num_glyphs; i++ ) + for ( i = 0; i < t42face->type1.num_glyphs; i++ ) { - FT_String* gname = face->type1.glyph_names[i]; + FT_String* gname = t42face->type1.glyph_names[i]; if ( glyph_name[0] == gname[0] && !ft_strcmp( glyph_name, gname ) ) - return (FT_UInt)ft_strtol( (const char *)face->type1.charstrings[i], - NULL, 10 ); + return (FT_UInt)ft_strtol( + (const char *)t42face->type1.charstrings[i], + NULL, + 10 ); } return 0; @@ -102,10 +110,13 @@ * */ - static const char* - t42_get_ps_font_name( T42_Face face ) + FT_CALLBACK_DEF( const char* ) + t42_get_ps_font_name( FT_Face face ) /* T42_Face */ { - return (const char*)face->type1.font_name; + T42_Face t42face = (T42_Face)face; + + + return (const char*)t42face->type1.font_name; } @@ -121,7 +132,7 @@ * */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) t42_ps_get_font_info( FT_Face face, PS_FontInfoRec* afont_info ) { @@ -131,7 +142,7 @@ } - static FT_Error + FT_CALLBACK_DEF( FT_Error ) t42_ps_get_font_extra( FT_Face face, PS_FontExtraRec* afont_extra ) { @@ -141,7 +152,7 @@ } - static FT_Int + FT_CALLBACK_DEF( FT_Int ) t42_ps_has_glyph_names( FT_Face face ) { FT_UNUSED( face ); diff --git a/thirdparty/freetype/src/type42/t42parse.c b/thirdparty/freetype/src/type42/t42parse.c index 6d765c8c10..764bbd4c4d 100644 --- a/thirdparty/freetype/src/type42/t42parse.c +++ b/thirdparty/freetype/src/type42/t42parse.c @@ -34,19 +34,19 @@ static void - t42_parse_font_matrix( T42_Face face, - T42_Loader loader ); + t42_parse_font_matrix( FT_Face face, + void* loader_ ); static void - t42_parse_encoding( T42_Face face, - T42_Loader loader ); + t42_parse_encoding( FT_Face face, + void* loader_ ); static void - t42_parse_charstrings( T42_Face face, - T42_Loader loader ); + t42_parse_charstrings( FT_Face face, + void* loader_ ); static void - t42_parse_sfnts( T42_Face face, - T42_Loader loader ); + t42_parse_sfnts( FT_Face face, + void* loader_ ); /* as Type42 fonts have no Private dict, */ @@ -241,12 +241,14 @@ static void - t42_parse_font_matrix( T42_Face face, - T42_Loader loader ) + t42_parse_font_matrix( FT_Face face, /* T42_Face */ + void* loader_ ) { - T42_Parser parser = &loader->parser; - FT_Matrix* matrix = &face->type1.font_matrix; - FT_Vector* offset = &face->type1.font_offset; + T42_Face t42face = (T42_Face)face; + T42_Loader loader = (T42_Loader)loader_; + T42_Parser parser = &loader->parser; + FT_Matrix* matrix = &t42face->type1.font_matrix; + FT_Vector* offset = &t42face->type1.font_offset; FT_Fixed temp[6]; FT_Fixed temp_scale; FT_Int result; @@ -299,14 +301,16 @@ static void - t42_parse_encoding( T42_Face face, - T42_Loader loader ) + t42_parse_encoding( FT_Face face, + void* loader_ ) { - T42_Parser parser = &loader->parser; + T42_Face t42face = (T42_Face)face; + T42_Loader loader = (T42_Loader)loader_; + T42_Parser parser = &loader->parser; FT_Byte* cur; - FT_Byte* limit = parser->root.limit; + FT_Byte* limit = parser->root.limit; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)t42face->psaux; T1_Skip_Spaces( parser ); @@ -322,7 +326,7 @@ /* and we must load it now */ if ( ft_isdigit( *cur ) || *cur == '[' ) { - T1_Encoding encode = &face->type1.encoding; + T1_Encoding encode = &t42face->type1.encoding; FT_Int count, n; PS_Table char_table = &loader->encoding_table; FT_Memory memory = parser->root.memory; @@ -493,8 +497,8 @@ T1_Skip_Spaces( parser ); } - face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; - parser->root.cursor = cur; + t42face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; } /* Otherwise, we should have either `StandardEncoding', */ @@ -503,15 +507,15 @@ { if ( cur + 17 < limit && ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + t42face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; else if ( cur + 15 < limit && ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + t42face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; else if ( cur + 18 < limit && ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + t42face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; else parser->root.error = FT_ERR( Ignore ); @@ -529,9 +533,11 @@ static void - t42_parse_sfnts( T42_Face face, - T42_Loader loader ) + t42_parse_sfnts( FT_Face face, + void* loader_ ) { + T42_Face t42face = (T42_Face)face; + T42_Loader loader = (T42_Loader)loader_; T42_Parser parser = &loader->parser; FT_Memory memory = parser->root.memory; FT_Byte* cur; @@ -548,8 +554,8 @@ T42_Load_Status status; /** There should only be one sfnts array, but free any previous. */ - FT_FREE( face->ttf_data ); - face->ttf_size = 0; + FT_FREE( t42face->ttf_data ); + t42face->ttf_size = 0; /* The format is */ /* */ @@ -580,7 +586,7 @@ old_string_size = 0; ttf_count = 0; ttf_reserved = 12; - if ( FT_QALLOC( face->ttf_data, ttf_reserved ) ) + if ( FT_QALLOC( t42face->ttf_data, ttf_reserved ) ) goto Fail; FT_TRACE2(( "\n" )); @@ -596,7 +602,7 @@ if ( *cur == ']' ) { parser->root.cursor++; - face->ttf_size = ttf_count; + t42face->ttf_size = ttf_count; goto Exit; } @@ -707,7 +713,7 @@ /* load offset table, 12 bytes */ if ( ttf_count < 12 ) { - face->ttf_data[ttf_count++] = string_buf[n]; + t42face->ttf_data[ttf_count++] = string_buf[n]; continue; } else @@ -715,7 +721,7 @@ FT_Long ttf_reserved_prev = ttf_reserved; - num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; + num_tables = 16 * t42face->ttf_data[4] + t42face->ttf_data[5]; status = BEFORE_TABLE_DIR; ttf_reserved = 12 + 16 * num_tables; @@ -729,7 +735,7 @@ goto Fail; } - if ( FT_QREALLOC( face->ttf_data, ttf_reserved_prev, + if ( FT_QREALLOC( t42face->ttf_data, ttf_reserved_prev, ttf_reserved ) ) goto Fail; } @@ -739,7 +745,7 @@ /* the offset table is read; read the table directory */ if ( ttf_count < ttf_reserved ) { - face->ttf_data[ttf_count++] = string_buf[n]; + t42face->ttf_data[ttf_count++] = string_buf[n]; continue; } else @@ -755,7 +761,7 @@ for ( i = 0; i < num_tables; i++ ) { - FT_Byte* p = face->ttf_data + 12 + 16 * i + 12; + FT_Byte* p = t42face->ttf_data + 12 + 16 * i + 12; len = FT_PEEK_ULONG( p ); @@ -781,7 +787,7 @@ FT_TRACE2(( " allocating %ld bytes\n", ttf_reserved )); FT_TRACE2(( "\n" )); - if ( FT_QREALLOC( face->ttf_data, ttf_reserved_prev, + if ( FT_QREALLOC( t42face->ttf_data, ttf_reserved_prev, ttf_reserved ) ) goto Fail; } @@ -795,7 +801,7 @@ error = FT_THROW( Invalid_File_Format ); goto Fail; } - face->ttf_data[ttf_count++] = string_buf[n]; + t42face->ttf_data[ttf_count++] = string_buf[n]; } } @@ -811,8 +817,8 @@ Exit: if ( parser->root.error ) { - FT_FREE( face->ttf_data ); - face->ttf_size = 0; + FT_FREE( t42face->ttf_data ); + t42face->ttf_size = 0; } if ( allocated ) FT_FREE( string_buf ); @@ -820,9 +826,11 @@ static void - t42_parse_charstrings( T42_Face face, - T42_Loader loader ) + t42_parse_charstrings( FT_Face face, /* T42_Face */ + void* loader_ ) { + T42_Face t42face = (T42_Face)face; + T42_Loader loader = (T42_Loader)loader_; T42_Parser parser = &loader->parser; PS_Table code_table = &loader->charstrings; PS_Table name_table = &loader->glyph_names; @@ -830,7 +838,7 @@ FT_Memory memory = parser->root.memory; FT_Error error; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)t42face->psaux; FT_Byte* cur; FT_Byte* limit = parser->root.limit; diff --git a/thirdparty/freetype/src/winfonts/winfnt.c b/thirdparty/freetype/src/winfonts/winfnt.c index fa73ae4a93..1160e4ef36 100644 --- a/thirdparty/freetype/src/winfonts/winfnt.c +++ b/thirdparty/freetype/src/winfonts/winfnt.c @@ -624,31 +624,34 @@ static FT_Error - fnt_cmap_init( FNT_CMap cmap, + fnt_cmap_init( FT_CMap cmap, /* FNT_CMap */ FT_Pointer pointer ) { - FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); - FNT_Font font = face->font; + FNT_CMap fntcmap = (FNT_CMap)cmap; + FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); + FNT_Font font = face->font; FT_UNUSED( pointer ); - cmap->first = (FT_UInt32) font->header.first_char; - cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 ); + fntcmap->first = (FT_UInt32)font->header.first_char; + fntcmap->count = (FT_UInt32)( font->header.last_char - + fntcmap->first + 1 ); return 0; } static FT_UInt - fnt_cmap_char_index( FNT_CMap cmap, + fnt_cmap_char_index( FT_CMap cmap, /* FNT_CMap */ FT_UInt32 char_code ) { - FT_UInt gindex = 0; + FNT_CMap fntcmap = (FNT_CMap)cmap; + FT_UInt gindex = 0; - char_code -= cmap->first; - if ( char_code < cmap->count ) + char_code -= fntcmap->first; + if ( char_code < fntcmap->count ) /* we artificially increase the glyph index; */ /* FNT_Load_Glyph reverts to the right one */ gindex = (FT_UInt)( char_code + 1 ); @@ -656,26 +659,27 @@ } - static FT_UInt32 - fnt_cmap_char_next( FNT_CMap cmap, + static FT_UInt + fnt_cmap_char_next( FT_CMap cmap, /* FNT_CMap */ FT_UInt32 *pchar_code ) { - FT_UInt gindex = 0; - FT_UInt32 result = 0; + FNT_CMap fntcmap = (FNT_CMap)cmap; + FT_UInt gindex = 0; + FT_UInt32 result = 0; FT_UInt32 char_code = *pchar_code + 1; - if ( char_code <= cmap->first ) + if ( char_code <= fntcmap->first ) { - result = cmap->first; + result = fntcmap->first; gindex = 1; } else { - char_code -= cmap->first; - if ( char_code < cmap->count ) + char_code -= fntcmap->first; + if ( char_code < fntcmap->count ) { - result = cmap->first + char_code; + result = fntcmap->first + char_code; gindex = (FT_UInt)( char_code + 1 ); } } diff --git a/thirdparty/harfbuzz/src/OT/Color/CBDT/CBDT.hh b/thirdparty/harfbuzz/src/OT/Color/CBDT/CBDT.hh index b125052344..457039bfc6 100644 --- a/thirdparty/harfbuzz/src/OT/Color/CBDT/CBDT.hh +++ b/thirdparty/harfbuzz/src/OT/Color/CBDT/CBDT.hh @@ -397,7 +397,6 @@ struct IndexSubtableRecord TRACE_SERIALIZE (this); auto *subtable = c->serializer->start_embed<IndexSubtable> (); - if (unlikely (!subtable)) return_trace (false); if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false); auto *old_subtable = get_subtable (base); @@ -545,7 +544,8 @@ struct IndexSubtableArray const IndexSubtableRecord*>> *lookup /* OUT */) const { bool start_glyph_is_set = false; - for (hb_codepoint_t new_gid = 0; new_gid < c->plan->num_output_glyphs (); new_gid++) + unsigned num_glyphs = c->plan->num_output_glyphs (); + for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++) { hb_codepoint_t old_gid; if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue; @@ -576,9 +576,6 @@ struct IndexSubtableArray { TRACE_SUBSET (this); - auto *dst = c->serializer->start_embed<IndexSubtableArray> (); - if (unlikely (!dst)) return_trace (false); - hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup; build_lookup (c, bitmap_size_context, &lookup); if (unlikely (!c->serializer->propagate_error (lookup))) @@ -993,12 +990,10 @@ CBLC::subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - auto *cblc_prime = c->serializer->start_embed<CBLC> (); - // Use a vector as a secondary buffer as the tables need to be built in parallel. hb_vector_t<char> cbdt_prime; - if (unlikely (!cblc_prime)) return_trace (false); + auto *cblc_prime = c->serializer->start_embed<CBLC> (); if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false); cblc_prime->version = version; diff --git a/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh b/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh index 2a47984294..6591bb4380 100644 --- a/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh +++ b/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh @@ -409,7 +409,6 @@ struct ColorLine { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); - if (unlikely (!out)) return_trace (false); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); @@ -1434,6 +1433,7 @@ struct PaintComposite { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + c->check_ops (this->min_size) && // PainComposite can get exponential src.sanitize (c, this) && backdrop.sanitize (c, this)); } @@ -2167,7 +2167,7 @@ struct COLR if (version == 0 && (!base_it || !layer_it)) return_trace (false); - COLR *colr_prime = c->serializer->start_embed<COLR> (); + auto *colr_prime = c->serializer->start_embed<COLR> (); if (unlikely (!c->serializer->extend_min (colr_prime))) return_trace (false); if (version == 0) diff --git a/thirdparty/harfbuzz/src/OT/Color/sbix/sbix.hh b/thirdparty/harfbuzz/src/OT/Color/sbix/sbix.hh index 46ad3fd58e..ce8693cfb1 100644 --- a/thirdparty/harfbuzz/src/OT/Color/sbix/sbix.hh +++ b/thirdparty/harfbuzz/src/OT/Color/sbix/sbix.hh @@ -48,7 +48,6 @@ struct SBIXGlyph { TRACE_SERIALIZE (this); SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> (); - if (unlikely (!new_glyph)) return_trace (nullptr); if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr); new_glyph->xOffset = xOffset; @@ -143,7 +142,6 @@ struct SBIXStrike unsigned int num_output_glyphs = c->plan->num_output_glyphs (); auto* out = c->serializer->start_embed<SBIXStrike> (); - if (unlikely (!out)) return_trace (false); auto snap = c->serializer->snapshot (); if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false); out->ppem = ppem; @@ -388,7 +386,6 @@ struct sbix TRACE_SERIALIZE (this); auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> (); - if (unlikely (!out)) return_trace (false); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); hb_vector_t<Offset32To<SBIXStrike>*> new_strikes; @@ -423,8 +420,6 @@ struct sbix { TRACE_SUBSET (this); - sbix *sbix_prime = c->serializer->start_embed<sbix> (); - if (unlikely (!sbix_prime)) return_trace (false); if (unlikely (!c->serializer->embed (this->version))) return_trace (false); if (unlikely (!c->serializer->embed (this->flags))) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh index 9ca88f788a..25056c9bc3 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh @@ -57,6 +57,9 @@ struct Coverage public: DEFINE_SIZE_UNION (2, format); +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh index 5d68e3d15e..3f598d40ef 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh @@ -79,7 +79,7 @@ struct CoverageFormat1_3 { if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2) { - for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + for (auto g : *glyphs) if (get_coverage (g) != NOT_COVERED) return true; return false; diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh index fa501d659d..9c87542356 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh @@ -122,7 +122,7 @@ struct CoverageFormat2_4 { if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) { - for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + for (auto g : *glyphs) if (get_coverage (g) != NOT_COVERED) return true; return false; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh b/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh index c1ff796199..d995ba0d4c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh @@ -49,8 +49,6 @@ struct AttachPoint : Array16Of<HBUINT16> { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); - if (unlikely (!out)) return_trace (false); - return_trace (out->serialize (c->serializer, + iter ())); } }; @@ -202,7 +200,6 @@ struct CaretValueFormat3 { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); - if (unlikely (!out)) return_trace (false); if (!c->serializer->embed (caretValueFormat)) return_trace (false); if (!c->serializer->embed (coordinate)) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh index e7e3c5c6d1..8684f60ca5 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh @@ -25,7 +25,9 @@ struct AnchorFormat3 bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); + if (unlikely (!c->check_struct (this))) return_trace (false); + + return_trace (xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); } void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED, @@ -35,9 +37,9 @@ struct AnchorFormat3 *x = font->em_fscale_x (xCoordinate); *y = font->em_fscale_y (yCoordinate); - if (font->x_ppem || font->num_coords) + if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); - if (font->y_ppem || font->num_coords) + if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); } @@ -45,7 +47,6 @@ struct AnchorFormat3 { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); - if (unlikely (!out)) return_trace (false); if (unlikely (!c->serializer->embed (format))) return_trace (false); if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false); if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh index c442efa1ea..bd9b189739 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh @@ -21,18 +21,25 @@ struct AnchorMatrix if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false); unsigned int count = rows * cols; if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false); + + if (c->lazy_some_gpos) + return_trace (true); + for (unsigned int i = 0; i < count; i++) if (!matrixZ[i].sanitize (c, this)) return_trace (false); return_trace (true); } - const Anchor& get_anchor (unsigned int row, unsigned int col, - unsigned int cols, bool *found) const + const Anchor& get_anchor (hb_ot_apply_context_t *c, + unsigned int row, unsigned int col, + unsigned int cols, bool *found) const { *found = false; if (unlikely (row >= rows || col >= cols)) return Null (Anchor); - *found = !matrixZ[row * cols + col].is_null (); - return this+matrixZ[row * cols + col]; + auto &offset = matrixZ[row * cols + col]; + if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor); + *found = !offset.is_null (); + return this+offset; } template <typename Iterator, diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh index b8773ba0aa..a459124dfe 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -278,7 +278,6 @@ struct CursivePosFormat1 const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); - if (unlikely (!out)) return_trace (false); auto it = + hb_zip (this+coverage, entryExitRecord) diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh index ff43ffb8c5..34e2ab8f6e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh @@ -28,7 +28,7 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove const Anchor& mark_anchor = this + record.markAnchor; bool found; - const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found); + const Anchor& glyph_anchor = anchors.get_anchor (c, glyph_index, mark_class, class_count, &found); /* If this subtable doesn't have an anchor for this base and this class, * return false such that the subsequent subtables have a chance at it. */ if (unlikely (!found)) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh index 31329dfcb5..05e6c0fa54 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -54,8 +54,9 @@ struct PairPosFormat2_4 return_trace (c->check_range ((const void *) values, count, stride) && - valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && - valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); + (c->lazy_some_gpos || + (valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && + valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)))); } bool intersects (const hb_set_t *glyphs) const @@ -298,11 +299,13 @@ struct PairPosFormat2_4 out->valueFormat2 = out->valueFormat2.drop_device_table_flags (); } + unsigned total_len = len1 + len2; + hb_vector_t<unsigned> class2_idxs (+ hb_range ((unsigned) class2Count) | hb_filter (klass2_map)); for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map)) { - for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) + for (unsigned class2_idx : class2_idxs) { - unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); + unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * total_len; valueFormat1.copy_values (c->serializer, out->valueFormat1, this, &values[idx], &c->plan->layout_variation_idx_delta_map); valueFormat2.copy_values (c->serializer, out->valueFormat2, this, &values[idx + len1], &c->plan->layout_variation_idx_delta_map); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh index 9faff49909..db301bb816 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh @@ -52,8 +52,9 @@ struct PairSet unsigned int count = len; const PairValueRecord *record = &firstPairValueRecord; - return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) && - closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride)); + return_trace (c->lazy_some_gpos || + (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) && + closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride))); } bool intersects (const hb_set_t *glyphs, diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh index 623e4e66b2..dff1f7316d 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -90,6 +90,7 @@ struct SinglePosFormat1 bool position_single (hb_font_t *font, + hb_blob_t *table_blob, hb_direction_t direction, hb_codepoint_t gid, hb_glyph_position_t &pos) const @@ -100,7 +101,7 @@ struct SinglePosFormat1 /* This is ugly... */ hb_buffer_t buffer; buffer.props.direction = direction; - OT::hb_ot_apply_context_t c (1, font, &buffer); + OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob); valueFormat.apply_value (&c, this, values, pos); return true; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh index e8f2d7c2c6..168ad3bb8c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh @@ -94,6 +94,7 @@ struct SinglePosFormat2 bool position_single (hb_font_t *font, + hb_blob_t *table_blob, hb_direction_t direction, hb_codepoint_t gid, hb_glyph_position_t &pos) const @@ -105,7 +106,7 @@ struct SinglePosFormat2 /* This is ugly... */ hb_buffer_t buffer; buffer.props.direction = direction; - OT::hb_ot_apply_context_t c (1, font, &buffer); + OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob); valueFormat.apply_value (&c, this, &values[index * valueFormat.get_len ()], diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh index 1aa451abcc..461a13d4b7 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh @@ -118,21 +118,25 @@ struct ValueFormat : HBUINT16 auto *cache = c->var_store_cache; /* pixel -> fractional pixel */ - if (format & xPlaDevice) { - if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store, cache); + if (format & xPlaDevice) + { + if (use_x_device) glyph_pos.x_offset += get_device (values, &ret, base, c->sanitizer).get_x_delta (font, store, cache); values++; } - if (format & yPlaDevice) { - if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store, cache); + if (format & yPlaDevice) + { + if (use_y_device) glyph_pos.y_offset += get_device (values, &ret, base, c->sanitizer).get_y_delta (font, store, cache); values++; } - if (format & xAdvDevice) { - if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store, cache); + if (format & xAdvDevice) + { + if (horizontal && use_x_device) glyph_pos.x_advance += get_device (values, &ret, base, c->sanitizer).get_x_delta (font, store, cache); values++; } - if (format & yAdvDevice) { + if (format & yAdvDevice) + { /* y_advance values grow downward but font-space grows upward, hence negation */ - if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store, cache); + if (!horizontal && use_y_device) glyph_pos.y_advance -= get_device (values, &ret, base, c->sanitizer).get_y_delta (font, store, cache); values++; } return ret; @@ -174,6 +178,9 @@ struct ValueFormat : HBUINT16 if (format & xAdvance) x_adv = copy_value (c, new_format, xAdvance, *values++); if (format & yAdvance) y_adv = copy_value (c, new_format, yAdvance, *values++); + if (!has_device ()) + return; + if (format & xPlaDevice) { add_delta_to_value (x_placement, base, values, layout_variation_idx_delta_map); @@ -233,14 +240,12 @@ struct ValueFormat : HBUINT16 if (format & ValueFormat::xAdvDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } if (format & ValueFormat::yAdvDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } @@ -277,11 +282,23 @@ struct ValueFormat : HBUINT16 { return *static_cast<Offset16To<Device> *> (value); } - static inline const Offset16To<Device>& get_device (const Value* value, bool *worked=nullptr) + static inline const Offset16To<Device>& get_device (const Value* value) { - if (worked) *worked |= bool (*value); return *static_cast<const Offset16To<Device> *> (value); } + static inline const Device& get_device (const Value* value, + bool *worked, + const void *base, + hb_sanitize_context_t &c) + { + if (worked) *worked |= bool (*value); + auto &offset = *static_cast<const Offset16To<Device> *> (value); + + if (unlikely (!offset.sanitize (&c, base))) + return Null(Device); + + return base + offset; + } void add_delta_to_value (HBINT16 *value, const void *base, @@ -340,25 +357,26 @@ struct ValueFormat : HBUINT16 bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const { TRACE_SANITIZE (this); - return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); + + if (unlikely (!c->check_range (values, get_size ()))) return_trace (false); + + if (c->lazy_some_gpos) + return_trace (true); + + return_trace (!has_device () || sanitize_value_devices (c, base, values)); } bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const { TRACE_SANITIZE (this); - unsigned int len = get_len (); + unsigned size = get_size (); - if (!c->check_range (values, count, get_size ())) return_trace (false); + if (!c->check_range (values, count, size)) return_trace (false); - if (!has_device ()) return_trace (true); + if (c->lazy_some_gpos) + return_trace (true); - for (unsigned int i = 0; i < count; i++) { - if (!sanitize_value_devices (c, base, values)) - return_trace (false); - values += len; - } - - return_trace (true); + return_trace (sanitize_values_stride_unsafe (c, base, values, count, size)); } /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh index 968bba0481..b849494d88 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh @@ -8,8 +8,6 @@ namespace OT { namespace Layout { namespace GSUB_impl { -typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t; - template<typename Iterator> static void SingleSubst_serialize (hb_serialize_context_t *c, Iterator it); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh index 8674a52fb5..db3fc55f77 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh @@ -13,12 +13,13 @@ struct Ligature public: typename Types::HBGlyphID ligGlyph; /* GlyphID of ligature to substitute */ - HeadlessArrayOf<typename Types::HBGlyphID> + HeadlessArray16Of<typename Types::HBGlyphID> component; /* Array of component GlyphIDs--start * with the second component--ordered * in writing direction */ public: DEFINE_SIZE_ARRAY (Types::size + 2, component); + DEFINE_SIZE_MAX (65536 * Types::HBGlyphID::static_size); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index 2c2e1aa44f..916fa281b3 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -191,7 +191,6 @@ struct ReverseChainSingleSubstFormat1 TRACE_SERIALIZE (this); auto *out = c->serializer->start_embed (this); - if (unlikely (!c->serializer->check_success (out))) return_trace (false); if (unlikely (!c->serializer->embed (this->format))) return_trace (false); if (unlikely (!c->serializer->embed (this->coverage))) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh index ae3292f329..a26cf8c6a6 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh @@ -53,7 +53,7 @@ struct Sequence if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { c->buffer->message (c->font, - "replaced glyph at %u (multiple subtitution)", + "replaced glyph at %u (multiple substitution)", c->buffer->idx - 1u); } diff --git a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh index d81fadf7c8..60858a5a58 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh @@ -90,24 +90,36 @@ struct CompositeGlyphRecord static void transform (const float (&matrix)[4], hb_array_t<contour_point_t> points) { - auto arrayZ = points.arrayZ; - unsigned count = points.length; - if (matrix[0] != 1.f || matrix[1] != 0.f || matrix[2] != 0.f || matrix[3] != 1.f) - for (unsigned i = 0; i < count; i++) - arrayZ[i].transform (matrix); + for (auto &point : points) + point.transform (matrix); } static void translate (const contour_point_t &trans, hb_array_t<contour_point_t> points) { - auto arrayZ = points.arrayZ; - unsigned count = points.length; - - if (trans.x != 0.f || trans.y != 0.f) - for (unsigned i = 0; i < count; i++) - arrayZ[i].translate (trans); + if (HB_OPTIMIZE_SIZE_VAL) + { + if (trans.x != 0.f || trans.y != 0.f) + for (auto &point : points) + point.translate (trans); + } + else + { + if (trans.x != 0.f && trans.y != 0.f) + for (auto &point : points) + point.translate (trans); + else + { + if (trans.x != 0.f) + for (auto &point : points) + point.x += trans.x; + else if (trans.y != 0.f) + for (auto &point : points) + point.y += trans.y; + } + } } void transform_points (hb_array_t<contour_point_t> points, @@ -131,9 +143,8 @@ struct CompositeGlyphRecord float matrix[4]; contour_point_t trans; get_transformation (matrix, trans); - points.alloc (points.length + 4); // For phantom points - if (unlikely (!points.resize (points.length + 1))) return false; - points.arrayZ[points.length - 1] = trans; + if (unlikely (!points.alloc (points.length + 4))) return false; // For phantom points + points.push (trans); return true; } @@ -382,7 +393,7 @@ struct CompositeGlyph { /* last 4 points in points_with_deltas are phantom points and should not be included */ if (i >= points_with_deltas.length - 4) { - free (o); + hb_free (o); return false; } diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh index 2bd5fe8206..2611c1e21d 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh @@ -114,8 +114,8 @@ struct Glyph if (type != EMPTY) { - plan->bounds_width_map.set (new_gid, xMax - xMin); - plan->bounds_height_map.set (new_gid, yMax - yMin); + plan->bounds_width_vec[new_gid] = xMax - xMin; + plan->bounds_height_vec[new_gid] = yMax - yMin; } unsigned len = all_points.length; @@ -124,10 +124,12 @@ struct Glyph float topSideY = all_points[len - 2].y; float bottomSideY = all_points[len - 1].y; + uint32_t hash = hb_hash (new_gid); + signed hori_aw = roundf (rightSideX - leftSideX); if (hori_aw < 0) hori_aw = 0; int lsb = roundf (xMin - leftSideX); - plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); + plan->hmtx_map.set_with_hash (new_gid, hash, hb_pair ((unsigned) hori_aw, lsb)); //flag value should be computed using non-empty glyphs if (type != EMPTY && lsb != xMin) plan->head_maxp_info.allXMinIsLsb = false; @@ -135,7 +137,7 @@ struct Glyph signed vert_aw = roundf (topSideY - bottomSideY); if (vert_aw < 0) vert_aw = 0; int tsb = roundf (topSideY - yMax); - plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); + plan->vmtx_map.set_with_hash (new_gid, hash, hb_pair ((unsigned) vert_aw, tsb)); } bool compile_header_bytes (const hb_subset_plan_t *plan, @@ -369,9 +371,11 @@ struct Glyph } #ifndef HB_NO_VAR - glyf_accelerator.gvar->apply_deltas_to_points (gid, - coords, - points.as_array ().sub_array (old_length)); + if (coords) + glyf_accelerator.gvar->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + phantom_only && type == SIMPLE); #endif // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it @@ -379,7 +383,7 @@ struct Glyph if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE) { if (unlikely (!points_with_deltas->resize (points.length))) return false; - points_with_deltas->copy_vector (points); + *points_with_deltas = points; } switch (type) { @@ -417,14 +421,17 @@ struct Glyph for (unsigned int i = 0; i < PHANTOM_COUNT; i++) phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; - float matrix[4]; - contour_point_t default_trans; - item.get_transformation (matrix, default_trans); + if (comp_points) // Empty in case of phantom_only + { + float matrix[4]; + contour_point_t default_trans; + item.get_transformation (matrix, default_trans); - /* Apply component transformation & translation (with deltas applied) */ - item.transform_points (comp_points, matrix, points[comp_index]); + /* Apply component transformation & translation (with deltas applied) */ + item.transform_points (comp_points, matrix, points[comp_index]); + } - if (item.is_anchored ()) + if (item.is_anchored () && !phantom_only) { unsigned int p1, p2; item.get_anchor_points (p1, p2); @@ -466,7 +473,10 @@ struct Glyph assert (record_points.length == item_num_points); auto component_coords = coords; - if (item.is_reset_unspecified_axes ()) + /* Copying coords is expensive; so we have put an arbitrary + * limit on the max number of coords for now. */ + if (item.is_reset_unspecified_axes () || + coords.length > HB_GLYF_VAR_COMPOSITE_MAX_AXES) component_coords = hb_array<int> (); coord_setter_t coord_setter (component_coords); diff --git a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh index 555bcee346..1d42cc2925 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh @@ -154,10 +154,9 @@ struct SimpleGlyph { int v = 0; - unsigned count = points_.length; - for (unsigned i = 0; i < count; i++) + for (auto &point : points_) { - unsigned flag = points_.arrayZ[i].flag; + unsigned flag = point.flag; if (flag & short_flag) { if (unlikely (p + 1 > end)) return false; @@ -175,7 +174,7 @@ struct SimpleGlyph p += HBINT16::static_size; } } - points_.arrayZ[i].*m = v; + point.*m = v; } return true; } @@ -192,9 +191,10 @@ struct SimpleGlyph unsigned old_length = points.length; points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy - if (!points.resize (points.length + num_points, false)) return false; + if (unlikely (!points.resize (points.length + num_points, false))) return false; auto points_ = points.as_array ().sub_array (old_length); - hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points); + if (!phantom_only) + hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points); if (phantom_only) return true; for (int i = 0; i < num_contours; i++) diff --git a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh index 26dc374eab..8099d3c126 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh @@ -22,7 +22,7 @@ struct SubsetGlyph bool serialize (hb_serialize_context_t *c, bool use_short_loca, - const hb_subset_plan_t *plan) + const hb_subset_plan_t *plan) const { TRACE_SERIALIZE (this); @@ -40,7 +40,7 @@ struct SubsetGlyph pad = 0; while (pad_length > 0) { - c->embed (pad); + (void) c->embed (pad); pad_length--; } diff --git a/thirdparty/harfbuzz/src/OT/glyf/VarCompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/VarCompositeGlyph.hh index 6dc6fd9ded..50cbece3ca 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/VarCompositeGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/VarCompositeGlyph.hh @@ -214,7 +214,7 @@ struct VarCompositeGlyphRecord points.alloc (points.length + num_points + 4); // For phantom points if (unlikely (!points.resize (points.length + num_points, false))) return false; contour_point_t *rec_points = points.arrayZ + (points.length - num_points); - memset (rec_points, 0, num_points * sizeof (rec_points[0])); + hb_memset (rec_points, 0, num_points * sizeof (rec_points[0])); unsigned fl = flags; diff --git a/thirdparty/harfbuzz/src/OT/glyf/coord-setter.hh b/thirdparty/harfbuzz/src/OT/glyf/coord-setter.hh index df64ed5af7..cf05929362 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/coord-setter.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/coord-setter.hh @@ -16,6 +16,8 @@ struct coord_setter_t int& operator [] (unsigned idx) { + if (unlikely (idx >= HB_GLYF_VAR_COMPOSITE_MAX_AXES)) + return Crap(int); if (coords.length < idx + 1) coords.resize (idx + 1); return coords[idx]; diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf-helpers.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf-helpers.hh index 30106b2b98..d0a5a132f0 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/glyf-helpers.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/glyf-helpers.hh @@ -12,24 +12,44 @@ namespace OT { namespace glyf_impl { -template<typename IteratorIn, typename IteratorOut, - hb_requires (hb_is_source_of (IteratorIn, unsigned int)), - hb_requires (hb_is_sink_of (IteratorOut, unsigned))> +template<typename IteratorIn, typename TypeOut, + hb_requires (hb_is_source_of (IteratorIn, unsigned int))> static void -_write_loca (IteratorIn&& it, bool short_offsets, IteratorOut&& dest) +_write_loca (IteratorIn&& it, + const hb_sorted_vector_t<hb_codepoint_pair_t> new_to_old_gid_list, + bool short_offsets, + TypeOut *dest, + unsigned num_offsets) { unsigned right_shift = short_offsets ? 1 : 0; - unsigned int offset = 0; - dest << 0; - + it - | hb_map ([=, &offset] (unsigned int padded_size) - { - offset += padded_size; - DEBUG_MSG (SUBSET, nullptr, "loca entry offset %u", offset); - return offset >> right_shift; - }) - | hb_sink (dest) - ; + unsigned offset = 0; + TypeOut value; + value = 0; + *dest++ = value; + hb_codepoint_t last = 0; + for (auto _ : new_to_old_gid_list) + { + hb_codepoint_t gid = _.first; + for (; last < gid; last++) + { + DEBUG_MSG (SUBSET, nullptr, "loca entry empty offset %u", offset); + *dest++ = value; + } + + unsigned padded_size = *it++; + offset += padded_size; + DEBUG_MSG (SUBSET, nullptr, "loca entry gid %u offset %u padded-size %u", gid, offset, padded_size); + value = offset >> right_shift; + *dest++ = value; + + last++; // Skip over gid + } + unsigned num_glyphs = num_offsets - 1; + for (; last < num_glyphs; last++) + { + DEBUG_MSG (SUBSET, nullptr, "loca entry empty offset %u", offset); + *dest++ = value; + } } static bool @@ -67,11 +87,14 @@ _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca) template<typename Iterator, hb_requires (hb_is_source_of (Iterator, unsigned int))> static bool -_add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca) +_add_loca_and_head (hb_subset_context_t *c, + Iterator padded_offsets, + bool use_short_loca) { - unsigned num_offsets = padded_offsets.len () + 1; + unsigned num_offsets = c->plan->num_output_glyphs () + 1; unsigned entry_size = use_short_loca ? 2 : 4; - char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets); + + char *loca_prime_data = (char *) hb_malloc (entry_size * num_offsets); if (unlikely (!loca_prime_data)) return false; @@ -79,9 +102,9 @@ _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_s entry_size, num_offsets, entry_size * num_offsets); if (use_short_loca) - _write_loca (padded_offsets, true, hb_array ((HBUINT16 *) loca_prime_data, num_offsets)); + _write_loca (padded_offsets, c->plan->new_to_old_gid_list, true, (HBUINT16 *) loca_prime_data, num_offsets); else - _write_loca (padded_offsets, false, hb_array ((HBUINT32 *) loca_prime_data, num_offsets)); + _write_loca (padded_offsets, c->plan->new_to_old_gid_list, false, (HBUINT32 *) loca_prime_data, num_offsets); hb_blob_t *loca_blob = hb_blob_create (loca_prime_data, entry_size * num_offsets, @@ -89,8 +112,8 @@ _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_s loca_prime_data, hb_free); - bool result = plan->add_table (HB_OT_TAG_loca, loca_blob) - && _add_head_and_set_loca_version (plan, use_short_loca); + bool result = c->plan->add_table (HB_OT_TAG_loca, loca_blob) + && _add_head_and_set_loca_version (c->plan, use_short_loca); hb_blob_destroy (loca_blob); return result; diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh index dd08dda6ee..6300cf4be0 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh @@ -85,75 +85,72 @@ struct glyf return_trace (false); } - glyf *glyf_prime = c->serializer->start_embed <glyf> (); - if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false); - hb_font_t *font = nullptr; if (c->plan->normalized_coords) { font = _create_font_for_instancing (c->plan); - if (unlikely (!font)) return false; + if (unlikely (!font)) + return_trace (false); } hb_vector_t<unsigned> padded_offsets; - unsigned num_glyphs = c->plan->num_output_glyphs (); - if (unlikely (!padded_offsets.resize (num_glyphs))) - { - hb_font_destroy (font); - return false; - } + if (unlikely (!padded_offsets.alloc (c->plan->new_to_old_gid_list.length, true))) + return_trace (false); hb_vector_t<glyf_impl::SubsetGlyph> glyphs; if (!_populate_subset_glyphs (c->plan, font, glyphs)) { hb_font_destroy (font); - return false; + return_trace (false); } if (font) hb_font_destroy (font); unsigned max_offset = 0; - for (unsigned i = 0; i < num_glyphs; i++) + for (auto &g : glyphs) { - padded_offsets[i] = glyphs[i].padded_size (); - max_offset += padded_offsets[i]; + unsigned size = g.padded_size (); + padded_offsets.push (size); + max_offset += size; } bool use_short_loca = false; if (likely (!c->plan->force_long_loca)) use_short_loca = max_offset < 0x1FFFF; - if (!use_short_loca) { - for (unsigned i = 0; i < num_glyphs; i++) - padded_offsets[i] = glyphs[i].length (); + if (!use_short_loca) + { + padded_offsets.resize (0); + for (auto &g : glyphs) + padded_offsets.push (g.length ()); } - bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan); + auto *glyf_prime = c->serializer->start_embed <glyf> (); + bool result = glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan); if (c->plan->normalized_coords && !c->plan->pinned_at_default) _free_compiled_subset_glyphs (glyphs); - if (!result) return false; - - if (unlikely (c->serializer->in_error ())) return_trace (false); + if (unlikely (!c->serializer->check_success (glyf_impl::_add_loca_and_head (c, + padded_offsets.iter (), + use_short_loca)))) + return_trace (false); - return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan, - padded_offsets.iter (), - use_short_loca))); + return result; } bool _populate_subset_glyphs (const hb_subset_plan_t *plan, hb_font_t *font, - hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const; + hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const; hb_font_t * _create_font_for_instancing (const hb_subset_plan_t *plan) const; void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> &glyphs) const { - for (unsigned i = 0; i < glyphs.length; i++) - glyphs[i].free_compiled_bytes (); + for (auto &g : glyphs) + g.free_compiled_bytes (); } protected: @@ -222,13 +219,14 @@ struct glyf_accelerator_t if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only))) return false; + unsigned count = all_points.length; + assert (count >= glyf_impl::PHANTOM_COUNT); + count -= glyf_impl::PHANTOM_COUNT; + if (consumer.is_consuming_contour_points ()) { - unsigned count = all_points.length; - assert (count >= glyf_impl::PHANTOM_COUNT); - count -= glyf_impl::PHANTOM_COUNT; - for (unsigned point_index = 0; point_index < count; point_index++) - consumer.consume_point (all_points[point_index]); + for (auto &point : all_points.as_array ().sub_array (0, count)) + consumer.consume_point (point); consumer.points_end (); } @@ -236,7 +234,7 @@ struct glyf_accelerator_t contour_point_t *phantoms = consumer.get_phantoms_sink (); if (phantoms) for (unsigned i = 0; i < glyf_impl::PHANTOM_COUNT; ++i) - phantoms[i] = all_points[all_points.length - glyf_impl::PHANTOM_COUNT + i]; + phantoms[i] = all_points.arrayZ[count + i]; return true; } @@ -299,6 +297,7 @@ struct glyf_accelerator_t if (extents) bounds = contour_bounds_t (); } + HB_ALWAYS_INLINE void consume_point (const contour_point_t &point) { bounds.add (point); } void points_end () { bounds.get_extents (font, extents, scaled); } @@ -431,16 +430,17 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const { OT::glyf_accelerator_t glyf (plan->source); - unsigned num_glyphs = plan->num_output_glyphs (); - if (!glyphs.resize (num_glyphs)) return false; + if (!glyphs.alloc (plan->new_to_old_gid_list.length, true)) return false; - for (auto p : plan->glyph_map->iter ()) + for (const auto &pair : plan->new_to_old_gid_list) { - unsigned new_gid = p.second; - glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid]; - subset_glyph.old_gid = p.first; + hb_codepoint_t new_gid = pair.first; + hb_codepoint_t old_gid = pair.second; + glyf_impl::SubsetGlyph *p = glyphs.push (); + glyf_impl::SubsetGlyph& subset_glyph = *p; + subset_glyph.old_gid = old_gid; - if (unlikely (new_gid == 0 && + if (unlikely (old_gid == 0 && new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) && !plan->normalized_coords) subset_glyph.source_glyph = glyf_impl::Glyph (); @@ -487,7 +487,7 @@ glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const { hb_variation_t var; var.tag = _.first; - var.value = _.second; + var.value = _.second.middle; vars.push (var); } diff --git a/thirdparty/harfbuzz/src/OT/glyf/path-builder.hh b/thirdparty/harfbuzz/src/OT/glyf/path-builder.hh index f7f732d336..f550524503 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/path-builder.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/path-builder.hh @@ -21,11 +21,11 @@ struct path_builder_t operator bool () const { return has_data; } bool has_data = false; - float x = 0.; - float y = 0.; + float x; + float y; - optional_point_t lerp (optional_point_t p, float t) - { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); } + optional_point_t mid (optional_point_t p) + { return optional_point_t ((x + p.x) * 0.5f, (y + p.y) * 0.5f); } } first_oncurve, first_offcurve, first_offcurve2, last_offcurve, last_offcurve2; path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_) : @@ -37,6 +37,7 @@ struct path_builder_t * https://stackoverflow.com/a/20772557 * * Cubic support added. */ + HB_ALWAYS_INLINE void consume_point (const contour_point_t &point) { bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE; @@ -46,7 +47,7 @@ struct path_builder_t bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC); #endif optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y)); - if (!first_oncurve) + if (unlikely (!first_oncurve)) { if (is_on_curve) { @@ -62,7 +63,7 @@ struct path_builder_t } else if (first_offcurve) { - optional_point_t mid = first_offcurve.lerp (p, .5f); + optional_point_t mid = first_offcurve.mid (p); first_oncurve = mid; last_offcurve = p; draw_session->move_to (mid.x, mid.y); @@ -98,7 +99,7 @@ struct path_builder_t } else { - optional_point_t mid = last_offcurve.lerp (p, .5f); + optional_point_t mid = last_offcurve.mid (p); if (is_cubic) { @@ -123,13 +124,13 @@ struct path_builder_t } } - if (point.is_end_point) + if (unlikely (point.is_end_point)) { if (first_offcurve && last_offcurve) { - optional_point_t mid = last_offcurve.lerp (first_offcurve2 ? - first_offcurve2 : - first_offcurve, .5f); + optional_point_t mid = last_offcurve.mid (first_offcurve2 ? + first_offcurve2 : + first_offcurve); if (last_offcurve2) draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, last_offcurve.x, last_offcurve.y, diff --git a/thirdparty/harfbuzz/src/OT/name/name.hh b/thirdparty/harfbuzz/src/OT/name/name.hh index c1839f3b68..c8de101345 100644 --- a/thirdparty/harfbuzz/src/OT/name/name.hh +++ b/thirdparty/harfbuzz/src/OT/name/name.hh @@ -359,7 +359,7 @@ struct name record.nameID = ids.name_id; record.length = 0; // handled in NameRecord copy() record.offset = 0; - memcpy (name_records, &record, NameRecord::static_size); + hb_memcpy (name_records, &record, NameRecord::static_size); name_records++; } #endif @@ -384,10 +384,7 @@ struct name bool subset (hb_subset_context_t *c) const { - TRACE_SUBSET (this); - - name *name_prime = c->serializer->start_embed<name> (); - if (unlikely (!name_prime)) return_trace (false); + auto *name_prime = c->serializer->start_embed<name> (); #ifdef HB_EXPERIMENTAL_API const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides = @@ -436,7 +433,7 @@ struct name if (!name_table_overrides->is_empty ()) { if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population (), true))) - return_trace (false); + return false; for (const auto& record_ids : name_table_overrides->keys ()) { if (name_table_overrides->get (record_ids).length == 0) @@ -448,13 +445,13 @@ struct name } #endif - return (name_prime->serialize (c->serializer, it, - std::addressof (this + stringOffset) + return name_prime->serialize (c->serializer, it, + std::addressof (this + stringOffset) #ifdef HB_EXPERIMENTAL_API - , insert_name_records - , name_table_overrides + , insert_name_records + , name_table_overrides #endif - )); + ); } bool sanitize_records (hb_sanitize_context_t *c) const diff --git a/thirdparty/harfbuzz/src/graph/classdef-graph.hh b/thirdparty/harfbuzz/src/graph/classdef-graph.hh index c2e24a7067..4ae0c13acc 100644 --- a/thirdparty/harfbuzz/src/graph/classdef-graph.hh +++ b/thirdparty/harfbuzz/src/graph/classdef-graph.hh @@ -94,7 +94,13 @@ struct ClassDef : public OT::ClassDef } hb_bytes_t class_def_copy = serializer.copy_bytes (); - c.add_buffer ((char *) class_def_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer. + if (!class_def_copy.arrayZ) return false; + // Give ownership to the context, it will cleanup the buffer. + if (!c.add_buffer ((char *) class_def_copy.arrayZ)) + { + hb_free ((char *) class_def_copy.arrayZ); + return false; + } auto& obj = c.graph.vertices_[dest_obj].obj; obj.head = (char *) class_def_copy.arrayZ; diff --git a/thirdparty/harfbuzz/src/graph/coverage-graph.hh b/thirdparty/harfbuzz/src/graph/coverage-graph.hh index 49d0936315..bd6e91a1f2 100644 --- a/thirdparty/harfbuzz/src/graph/coverage-graph.hh +++ b/thirdparty/harfbuzz/src/graph/coverage-graph.hh @@ -118,7 +118,13 @@ struct Coverage : public OT::Layout::Common::Coverage } hb_bytes_t coverage_copy = serializer.copy_bytes (); - c.add_buffer ((char *) coverage_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer. + if (!coverage_copy.arrayZ) return false; + // Give ownership to the context, it will cleanup the buffer. + if (!c.add_buffer ((char *) coverage_copy.arrayZ)) + { + hb_free ((char *) coverage_copy.arrayZ); + return false; + } auto& obj = c.graph.vertices_[dest_obj].obj; obj.head = (char *) coverage_copy.arrayZ; diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh index 294a999918..53d0bc94e1 100644 --- a/thirdparty/harfbuzz/src/graph/graph.hh +++ b/thirdparty/harfbuzz/src/graph/graph.hh @@ -359,7 +359,6 @@ struct graph_t ~graph_t () { - vertices_.fini (); for (char* b : buffers) hb_free (b); } @@ -401,9 +400,10 @@ struct graph_t return vertices_[i].obj; } - void add_buffer (char* buffer) + bool add_buffer (char* buffer) { buffers.push (buffer); + return !buffers.in_error (); } /* @@ -732,8 +732,7 @@ struct graph_t remap_obj_indices (index_map, parents.iter (), true); // Update roots set with new indices as needed. - uint32_t next = HB_SET_VALUE_INVALID; - while (roots.next (&next)) + for (auto next : roots) { const uint32_t *v; if (index_map.has (next, &v)) diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-context.cc b/thirdparty/harfbuzz/src/graph/gsubgpos-context.cc index b2044426d4..d66eb49cfd 100644 --- a/thirdparty/harfbuzz/src/graph/gsubgpos-context.cc +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-context.cc @@ -52,7 +52,11 @@ unsigned gsubgpos_graph_context_t::create_node (unsigned size) if (!buffer) return -1; - add_buffer (buffer); + if (!add_buffer (buffer)) { + // Allocation did not get stored for freeing later. + hb_free (buffer); + return -1; + } return graph.new_node (buffer, buffer + size); } diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh index 9fe9662e64..26b7cfe4d4 100644 --- a/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh @@ -47,9 +47,9 @@ struct gsubgpos_graph_context_t HB_INTERNAL unsigned create_node (unsigned size); - void add_buffer (char* buffer) + bool add_buffer (char* buffer) { - graph.add_buffer (buffer); + return graph.add_buffer (buffer); } private: diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh index c170638409..78d5096325 100644 --- a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh @@ -166,7 +166,7 @@ struct Lookup : public OT::Lookup } if (all_new_subtables) { - add_sub_tables (c, this_index, type, all_new_subtables); + return add_sub_tables (c, this_index, type, all_new_subtables); } return true; @@ -184,7 +184,7 @@ struct Lookup : public OT::Lookup return sub_table->split_subtables (c, parent_idx, objidx); } - void add_sub_tables (gsubgpos_graph_context_t& c, + bool add_sub_tables (gsubgpos_graph_context_t& c, unsigned this_index, unsigned type, hb_vector_t<hb_pair_t<unsigned, hb_vector_t<unsigned>>>& subtable_ids) @@ -200,7 +200,12 @@ struct Lookup : public OT::Lookup size_t new_size = v.table_size () + new_subtable_count * OT::Offset16::static_size; char* buffer = (char*) hb_calloc (1, new_size); - c.add_buffer (buffer); + if (!buffer) return false; + if (!c.add_buffer (buffer)) + { + hb_free (buffer); + return false; + } hb_memcpy (buffer, v.obj.head, v.table_size()); v.obj.head = buffer; @@ -239,6 +244,7 @@ struct Lookup : public OT::Lookup // The head location of the lookup has changed, invalidating the lookups map entry // in the context. Update the map. c.lookups.set (this_index, new_lookup); + return true; } void fix_existing_subtable_links (gsubgpos_graph_context_t& c, diff --git a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh index 1c13eb24f9..f655b71558 100644 --- a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh @@ -215,7 +215,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType auto gid_and_class = + coverage->iter () | hb_map_retains_sorting ([&] (hb_codepoint_t gid) { - return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1->get_class (gid)); + return hb_codepoint_pair_t (gid, class_def_1->get_class (gid)); }) ; class_def_size_estimator_t estimator (gid_and_class); @@ -386,14 +386,14 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType auto klass_map = + coverage_table->iter () | hb_map_retains_sorting ([&] (hb_codepoint_t gid) { - return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1_table->get_class (gid)); + return hb_codepoint_pair_t (gid, class_def_1_table->get_class (gid)); }) | hb_filter ([&] (hb_codepoint_t klass) { return klass >= start && klass < end; }, hb_second) - | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, hb_codepoint_t> gid_and_class) { + | hb_map_retains_sorting ([&] (hb_codepoint_pair_t gid_and_class) { // Classes must be from 0...N so subtract start - return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid_and_class.first, gid_and_class.second - start); + return hb_codepoint_pair_t (gid_and_class.first, gid_and_class.second - start); }) ; @@ -519,7 +519,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType auto klass_map = + coverage.table->iter () | hb_map_retains_sorting ([&] (hb_codepoint_t gid) { - return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1.table->get_class (gid)); + return hb_codepoint_pair_t (gid, class_def_1.table->get_class (gid)); }) | hb_filter ([&] (hb_codepoint_t klass) { return klass < count; diff --git a/thirdparty/harfbuzz/src/graph/serialize.hh b/thirdparty/harfbuzz/src/graph/serialize.hh index 2e0b845baa..06e4bf44d8 100644 --- a/thirdparty/harfbuzz/src/graph/serialize.hh +++ b/thirdparty/harfbuzz/src/graph/serialize.hh @@ -226,6 +226,9 @@ inline hb_blob_t* serialize (const graph_t& graph) { hb_vector_t<char> buffer; size_t size = graph.total_size_in_bytes (); + + if (!size) return hb_blob_get_empty (); + if (!buffer.alloc (size)) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer."); return nullptr; diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index da383e050a..374965d56e 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -87,6 +87,19 @@ static inline constexpr uint16_t hb_uint16_swap (uint16_t v) static inline constexpr uint32_t hb_uint32_swap (uint32_t v) { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } +#ifndef HB_FAST_INT_ACCESS +#if defined(__OPTIMIZE__) && \ + defined(__BYTE_ORDER) && \ + (__BYTE_ORDER == __BIG_ENDIAN || \ + (__BYTE_ORDER == __LITTLE_ENDIAN && \ + hb_has_builtin(__builtin_bswap16) && \ + hb_has_builtin(__builtin_bswap32))) +#define HB_FAST_INT_ACCESS 1 +#else +#define HB_FAST_INT_ACCESS 0 +#endif +#endif + template <typename Type, int Bytes = sizeof (Type)> struct BEInt; template <typename Type> @@ -101,21 +114,25 @@ struct BEInt<Type, 1> template <typename Type> struct BEInt<Type, 2> { + struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; + public: BEInt () = default; - constexpr BEInt (Type V) : v {uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} - struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; - constexpr operator Type () const - { -#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ - defined(__BYTE_ORDER) && \ - (__BYTE_ORDER == __BIG_ENDIAN || \ - (__BYTE_ORDER == __LITTLE_ENDIAN && \ - hb_has_builtin(__builtin_bswap16))) - /* Spoon-feed the compiler a big-endian integer with alignment 1. - * https://github.com/harfbuzz/harfbuzz/pull/1398 */ + BEInt (Type V) +#if HB_FAST_INT_ACCESS +#if __BYTE_ORDER == __LITTLE_ENDIAN + { ((packed_uint16_t *) v)->v = __builtin_bswap16 (V); } +#else /* __BYTE_ORDER == __BIG_ENDIAN */ + { ((packed_uint16_t *) v)->v = V; } +#endif +#else + : v {uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} +#endif + + constexpr operator Type () const { +#if HB_FAST_INT_ACCESS #if __BYTE_ORDER == __LITTLE_ENDIAN return __builtin_bswap16 (((packed_uint16_t *) v)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ @@ -146,22 +163,27 @@ struct BEInt<Type, 3> template <typename Type> struct BEInt<Type, 4> { + struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + public: BEInt () = default; - constexpr BEInt (Type V) : v {uint8_t ((V >> 24) & 0xFF), - uint8_t ((V >> 16) & 0xFF), - uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} - struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + BEInt (Type V) +#if HB_FAST_INT_ACCESS +#if __BYTE_ORDER == __LITTLE_ENDIAN + { ((packed_uint32_t *) v)->v = __builtin_bswap32 (V); } +#else /* __BYTE_ORDER == __BIG_ENDIAN */ + { ((packed_uint32_t *) v)->v = V; } +#endif +#else + : v {uint8_t ((V >> 24) & 0xFF), + uint8_t ((V >> 16) & 0xFF), + uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} +#endif + constexpr operator Type () const { -#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ - defined(__BYTE_ORDER) && \ - (__BYTE_ORDER == __BIG_ENDIAN || \ - (__BYTE_ORDER == __LITTLE_ENDIAN && \ - hb_has_builtin(__builtin_bswap32))) - /* Spoon-feed the compiler a big-endian integer with alignment 1. - * https://github.com/harfbuzz/harfbuzz/pull/1398 */ +#if HB_FAST_INT_ACCESS #if __BYTE_ORDER == __LITTLE_ENDIAN return __builtin_bswap32 (((packed_uint32_t *) v)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ @@ -231,12 +253,119 @@ struct } HB_FUNCOBJ (hb_bool); + +/* The MIT License + + Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + + +// Compression function for Merkle-Damgard construction. +// This function is generated using the framework provided. +#define mix(h) ( \ + (h) ^= (h) >> 23, \ + (h) *= 0x2127599bf4325c37ULL, \ + (h) ^= (h) >> 47) + +static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) +{ + struct __attribute__((packed)) packed_uint64_t { uint64_t v; }; + const uint64_t m = 0x880355f21e6d1965ULL; + const packed_uint64_t *pos = (const packed_uint64_t *)buf; + const packed_uint64_t *end = pos + (len / 8); + const unsigned char *pos2; + uint64_t h = seed ^ (len * m); + uint64_t v; + +#ifndef HB_OPTIMIZE_SIZE + if (((uintptr_t) pos & 7) == 0) + { + while (pos != end) + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + v = * (const uint64_t *) (pos++); +#pragma GCC diagnostic pop + h ^= mix(v); + h *= m; + } + } + else +#endif + { + while (pos != end) + { + v = pos++->v; + h ^= mix(v); + h *= m; + } + } + + pos2 = (const unsigned char*)pos; + v = 0; + + switch (len & 7) { + case 7: v ^= (uint64_t)pos2[6] << 48; HB_FALLTHROUGH; + case 6: v ^= (uint64_t)pos2[5] << 40; HB_FALLTHROUGH; + case 5: v ^= (uint64_t)pos2[4] << 32; HB_FALLTHROUGH; + case 4: v ^= (uint64_t)pos2[3] << 24; HB_FALLTHROUGH; + case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH; + case 2: v ^= (uint64_t)pos2[1] << 8; HB_FALLTHROUGH; + case 1: v ^= (uint64_t)pos2[0]; + h ^= mix(v); + h *= m; + } + + return mix(h); +} + +static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed) +{ + // the following trick converts the 64-bit hashcode to Fermat + // residue, which shall retain information from both the higher + // and lower parts of hashcode. + uint64_t h = fasthash64(buf, len, seed); + return h - (h >> 32); +} + struct { private: template <typename T> constexpr auto - impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) + impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) + + // Horrible: std:hash() of integers seems to be identity in gcc / clang?! + // https://github.com/harfbuzz/harfbuzz/pull/4228 + // + // For performance characteristics see: + // https://github.com/harfbuzz/harfbuzz/pull/4228#issuecomment-1565079537 + template <typename T, + hb_enable_if (std::is_integral<T>::value && sizeof (T) <= sizeof (uint32_t))> constexpr auto + impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, v * 2654435761u /* Knuh's multiplicative hash */) + template <typename T, + hb_enable_if (std::is_integral<T>::value && sizeof (T) > sizeof (uint32_t))> constexpr auto + impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (v ^ (v >> 32)) * 2654435761u /* Knuth's multiplicative hash */) template <typename T> constexpr auto impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v))) @@ -551,6 +680,8 @@ struct hb_pair_t template <typename T1, typename T2> static inline hb_pair_t<T1, T2> hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); } +typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t; + struct { template <typename Pair> constexpr typename Pair::first_t @@ -853,7 +984,7 @@ static inline void * hb_memset (void *s, int c, unsigned int n) { /* It's illegal to pass NULL to memset(), even if n is zero. */ - if (unlikely (!n)) return 0; + if (unlikely (!n)) return s; return memset (s, c, n); } diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh index 1a22e15c0f..760f90259c 100644 --- a/thirdparty/harfbuzz/src/hb-array.hh +++ b/thirdparty/harfbuzz/src/hb-array.hh @@ -75,11 +75,25 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> */ typedef Type& __item_t__; static constexpr bool is_random_access_iterator = true; + static constexpr bool has_fast_len = true; + Type& __item__ () const + { + if (unlikely (!length)) return CrapOrNull (Type); + return *arrayZ; + } Type& __item_at__ (unsigned i) const { if (unlikely (i >= length)) return CrapOrNull (Type); return arrayZ[i]; } + void __next__ () + { + if (unlikely (!length)) + return; + length--; + backwards_length++; + arrayZ++; + } void __forward__ (unsigned n) { if (unlikely (n > length)) @@ -88,6 +102,14 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> backwards_length += n; arrayZ += n; } + void __prev__ () + { + if (unlikely (!backwards_length)) + return; + length++; + backwards_length--; + arrayZ--; + } void __rewind__ (unsigned n) { if (unlikely (n > backwards_length)) @@ -123,6 +145,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> uint32_t hash () const { // FNV-1a hash function + // https://github.com/harfbuzz/harfbuzz/pull/4228 uint32_t current = /*cbf29ce4*/0x84222325; for (auto &v : *this) { @@ -326,6 +349,7 @@ struct hb_sorted_array_t : HB_ITER_USING (iter_base_t); static constexpr bool is_random_access_iterator = true; static constexpr bool is_sorted_iterator = true; + static constexpr bool has_fast_len = true; hb_sorted_array_t () = default; hb_sorted_array_t (const hb_sorted_array_t&) = default; @@ -453,55 +477,21 @@ inline bool hb_array_t<const unsigned char>::operator == (const hb_array_t<const /* Specialize hash() for byte arrays. */ +#ifndef HB_OPTIMIZE_SIZE_MORE template <> inline uint32_t hb_array_t<const char>::hash () const { - // FNV-1a hash function - uint32_t current = /*cbf29ce4*/0x84222325; - unsigned i = 0; - -#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ - ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) - struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; - for (; i + 4 <= this->length; i += 4) - { - current = current ^ hb_hash ((uint32_t) ((const packed_uint32_t *) &this->arrayZ[i])->v); - current = current * 16777619; - } -#endif - - for (; i < this->length; i++) - { - current = current ^ hb_hash (this->arrayZ[i]); - current = current * 16777619; - } - return current; + // https://github.com/harfbuzz/harfbuzz/pull/4228 + return fasthash32(arrayZ, length, 0xf437ffe6 /* magic? */); } template <> inline uint32_t hb_array_t<const unsigned char>::hash () const { - // FNV-1a hash function - uint32_t current = /*cbf29ce4*/0x84222325; - unsigned i = 0; - -#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ - ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) - struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; - for (; i + 4 <= this->length; i += 4) - { - current = current ^ hb_hash ((uint32_t) ((const packed_uint32_t *) &this->arrayZ[i])->v); - current = current * 16777619; - } -#endif - - for (; i < this->length; i++) - { - current = current ^ hb_hash (this->arrayZ[i]); - current = current * 16777619; - } - return current; + // https://github.com/harfbuzz/harfbuzz/pull/4228 + return fasthash32(arrayZ, length, 0xf437ffe6 /* magic? */); } +#endif typedef hb_array_t<const char> hb_bytes_t; diff --git a/thirdparty/harfbuzz/src/hb-atomic.hh b/thirdparty/harfbuzz/src/hb-atomic.hh index a6283de140..303dfe6d04 100644 --- a/thirdparty/harfbuzz/src/hb-atomic.hh +++ b/thirdparty/harfbuzz/src/hb-atomic.hh @@ -204,6 +204,7 @@ struct hb_atomic_ptr_t hb_atomic_ptr_t () = default; constexpr hb_atomic_ptr_t (T* v) : v (v) {} + hb_atomic_ptr_t (const hb_atomic_ptr_t &other) = delete; void init (T* v_ = nullptr) { set_relaxed (v_); } void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } diff --git a/thirdparty/harfbuzz/src/hb-bimap.hh b/thirdparty/harfbuzz/src/hb-bimap.hh index 9edefd9710..4006fc4ebd 100644 --- a/thirdparty/harfbuzz/src/hb-bimap.hh +++ b/thirdparty/harfbuzz/src/hb-bimap.hh @@ -39,10 +39,10 @@ struct hb_bimap_t back_map.reset (); } - void resize (unsigned pop) + void alloc (unsigned pop) { - forw_map.resize (pop); - back_map.resize (pop); + forw_map.alloc (pop); + back_map.alloc (pop); } bool in_error () const { return forw_map.in_error () || back_map.in_error (); } @@ -83,7 +83,6 @@ struct hb_bimap_t unsigned int get_population () const { return forw_map.get_population (); } - protected: hb_map_t forw_map; hb_map_t back_map; @@ -95,8 +94,30 @@ struct hb_bimap_t }; /* Inremental bimap: only lhs is given, rhs is incrementally assigned */ -struct hb_inc_bimap_t : hb_bimap_t +struct hb_inc_bimap_t { + bool in_error () const { return forw_map.in_error () || back_map.in_error (); } + + unsigned int get_population () const { return forw_map.get_population (); } + + void reset () + { + forw_map.reset (); + back_map.reset (); + } + + void alloc (unsigned pop) + { + forw_map.alloc (pop); + back_map.alloc (pop); + } + + void clear () + { + forw_map.clear (); + back_map.resize (0); + } + /* Add a mapping from lhs to rhs with a unique value if lhs is unknown. * Return the rhs value as the result. */ @@ -105,32 +126,41 @@ struct hb_inc_bimap_t : hb_bimap_t hb_codepoint_t rhs = forw_map[lhs]; if (rhs == HB_MAP_VALUE_INVALID) { - rhs = next_value++; - set (lhs, rhs); + rhs = back_map.length; + forw_map.set (lhs, rhs); + back_map.push (lhs); } return rhs; } hb_codepoint_t skip () - { return next_value++; } + { + hb_codepoint_t start = back_map.length; + back_map.push (HB_MAP_VALUE_INVALID); + return start; + } hb_codepoint_t skip (unsigned count) - { return next_value += count; } + { + hb_codepoint_t start = back_map.length; + for (unsigned i = 0; i < count; i++) + back_map.push (HB_MAP_VALUE_INVALID); + return start; + } hb_codepoint_t get_next_value () const - { return next_value; } + { return back_map.length; } void add_set (const hb_set_t *set) { - hb_codepoint_t i = HB_SET_VALUE_INVALID; - while (hb_set_next (set, &i)) add (i); + for (auto i : *set) add (i); } /* Create an identity map. */ bool identity (unsigned int size) { clear (); - for (hb_codepoint_t i = 0; i < size; i++) set (i, i); + for (hb_codepoint_t i = 0; i < size; i++) add (i); return !in_error (); } @@ -145,20 +175,30 @@ struct hb_inc_bimap_t : hb_bimap_t { hb_codepoint_t count = get_population (); hb_vector_t <hb_codepoint_t> work; - work.resize (count); + if (unlikely (!work.resize (count, false))) return; for (hb_codepoint_t rhs = 0; rhs < count; rhs++) - work[rhs] = back_map[rhs]; + work.arrayZ[rhs] = back_map[rhs]; work.qsort (cmp_id); clear (); for (hb_codepoint_t rhs = 0; rhs < count; rhs++) - set (work[rhs], rhs); + add (work.arrayZ[rhs]); } + hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); } + hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map[rhs]; } + + hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); } + bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); } + protected: - unsigned int next_value = 0; + hb_map_t forw_map; + hb_vector_t<hb_codepoint_t> back_map; + + public: + auto keys () const HB_AUTO_RETURN (+ back_map.iter()) }; #endif /* HB_BIMAP_HH */ diff --git a/thirdparty/harfbuzz/src/hb-bit-page.hh b/thirdparty/harfbuzz/src/hb-bit-page.hh index 9b027ac590..e578d2643f 100644 --- a/thirdparty/harfbuzz/src/hb-bit-page.hh +++ b/thirdparty/harfbuzz/src/hb-bit-page.hh @@ -104,10 +104,7 @@ struct hb_bit_page_t } uint32_t hash () const { - return - + hb_iter (v) - | hb_reduce ([] (uint32_t h, const elt_t &_) { return h * 31 + hb_hash (_); }, (uint32_t) 0u) - ; + return hb_bytes_t ((const char *) &v, sizeof (v)).hash (); } void add (hb_codepoint_t g) { elt (g) |= mask (g); } diff --git a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh index 1eb1b1c209..e765a479ae 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh @@ -136,7 +136,7 @@ struct hb_bit_set_invertible_t /* Sink interface. */ hb_bit_set_invertible_t& operator << (hb_codepoint_t v) { add (v); return *this; } - hb_bit_set_invertible_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) + hb_bit_set_invertible_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } bool intersects (hb_codepoint_t first, hb_codepoint_t last) const @@ -162,7 +162,7 @@ struct hb_bit_set_invertible_t auto it1 = iter (); auto it2 = other.iter (); return hb_all (+ hb_zip (it1, it2) - | hb_map ([](hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) { return _.first == _.second; })); + | hb_map ([](hb_codepoint_pair_t _) { return _.first == _.second; })); } } @@ -345,6 +345,7 @@ struct hb_bit_set_invertible_t struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> { static constexpr bool is_sorted_iterator = true; + static constexpr bool has_fast_len = true; iter_t (const hb_bit_set_invertible_t &s_ = Null (hb_bit_set_invertible_t), bool init = true) : s (&s_), v (INVALID), l(0) { @@ -363,7 +364,7 @@ struct hb_bit_set_invertible_t unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const - { return s != o.s || v != o.v; } + { return v != o.v || s != o.s; } protected: const hb_bit_set_invertible_t *s; diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh index d290f6114c..a84d751fb3 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set.hh @@ -134,7 +134,11 @@ struct hb_bit_set_t { uint32_t h = 0; for (auto &map : page_map) - h = h * 31 + hb_hash (map.major) + hb_hash (pages[map.index]); + { + auto &page = pages.arrayZ[map.index]; + if (unlikely (page.is_empty ())) continue; + h = h * 31 + hb_hash (map.major) + hb_hash (page); + } return h; } @@ -342,7 +346,7 @@ struct hb_bit_set_t /* Sink interface. */ hb_bit_set_t& operator << (hb_codepoint_t v) { add (v); return *this; } - hb_bit_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) + hb_bit_set_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } bool intersects (hb_codepoint_t first, hb_codepoint_t last) const @@ -862,6 +866,7 @@ struct hb_bit_set_t struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> { static constexpr bool is_sorted_iterator = true; + static constexpr bool has_fast_len = true; iter_t (const hb_bit_set_t &s_ = Null (hb_bit_set_t), bool init = true) : s (&s_), v (INVALID), l(0) { diff --git a/thirdparty/harfbuzz/src/hb-buffer-verify.cc b/thirdparty/harfbuzz/src/hb-buffer-verify.cc index f111b2d8dc..15a53919de 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-verify.cc +++ b/thirdparty/harfbuzz/src/hb-buffer-verify.cc @@ -162,14 +162,8 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, hb_buffer_set_flags (fragment, flags); hb_buffer_append (fragment, text_buffer, text_start, text_end); - if (!hb_shape_full (font, fragment, features, num_features, shapers)) - { - buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment."); - hb_buffer_destroy (reconstruction); - hb_buffer_destroy (fragment); - return false; - } - else if (!fragment->successful || fragment->shaping_failed) + if (!hb_shape_full (font, fragment, features, num_features, shapers) || + fragment->successful || fragment->shaping_failed) { hb_buffer_destroy (reconstruction); hb_buffer_destroy (fragment); @@ -185,15 +179,18 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, } bool ret = true; - hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); - if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH) + if (likely (reconstruction->successful)) { - buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed."); - ret = false; + hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); + if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH) + { + buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed."); + ret = false; - /* Return the reconstructed result instead so it can be inspected. */ - hb_buffer_set_length (buffer, 0); - hb_buffer_append (buffer, reconstruction, 0, -1); + /* Return the reconstructed result instead so it can be inspected. */ + hb_buffer_set_length (buffer, 0); + hb_buffer_append (buffer, reconstruction, 0, -1); + } } hb_buffer_destroy (reconstruction); @@ -316,28 +313,13 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, /* * Shape the two fragment streams. */ - if (!hb_shape_full (font, fragments[0], features, num_features, shapers)) - { - buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment."); - ret = false; - goto out; - } - else if (!fragments[0]->successful || fragments[0]->shaping_failed) - { - ret = true; - goto out; - } - if (!hb_shape_full (font, fragments[1], features, num_features, shapers)) - { - buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment."); - ret = false; + if (!hb_shape_full (font, fragments[0], features, num_features, shapers) || + !fragments[0]->successful || fragments[0]->shaping_failed) goto out; - } - else if (!fragments[1]->successful || fragments[1]->shaping_failed) - { - ret = true; + + if (!hb_shape_full (font, fragments[1], features, num_features, shapers) || + !fragments[1]->successful || fragments[1]->shaping_failed) goto out; - } if (!forward) { @@ -377,21 +359,23 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, hb_buffer_reverse (reconstruction); } - /* - * Diff results. - */ - diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); - if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH) + if (likely (reconstruction->successful)) { - buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed."); - ret = false; + /* + * Diff results. + */ + diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); + if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH) + { + buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed."); + ret = false; - /* Return the reconstructed result instead so it can be inspected. */ - hb_buffer_set_length (buffer, 0); - hb_buffer_append (buffer, reconstruction, 0, -1); + /* Return the reconstructed result instead so it can be inspected. */ + hb_buffer_set_length (buffer, 0); + hb_buffer_append (buffer, reconstruction, 0, -1); + } } - out: hb_buffer_destroy (reconstruction); hb_buffer_destroy (fragments[0]); diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh index 7a97fc7168..4d48b7f167 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.hh +++ b/thirdparty/harfbuzz/src/hb-buffer.hh @@ -493,6 +493,13 @@ struct hb_buffer_t HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size); + HB_NODISCARD bool resize (unsigned length) + { + assert (!have_output); + if (unlikely (!ensure (length))) return false; + len = length; + return true; + } HB_NODISCARD bool ensure (unsigned int size) { return likely (!size || size < allocated) ? true : enlarge (size); } diff --git a/thirdparty/harfbuzz/src/hb-cache.hh b/thirdparty/harfbuzz/src/hb-cache.hh index 8371465c6c..6d8a54cf10 100644 --- a/thirdparty/harfbuzz/src/hb-cache.hh +++ b/thirdparty/harfbuzz/src/hb-cache.hh @@ -62,14 +62,12 @@ struct hb_cache_t static_assert ((key_bits >= cache_bits), ""); static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), ""); - hb_cache_t () { init (); } - - void init () { clear (); } + hb_cache_t () { clear (); } void clear () { - for (unsigned i = 0; i < ARRAY_LENGTH (values); i++) - values[i] = -1; + for (auto &v : values) + v = -1; } bool get (unsigned int key, unsigned int *value) const diff --git a/thirdparty/harfbuzz/src/hb-cairo-utils.cc b/thirdparty/harfbuzz/src/hb-cairo-utils.cc index 0f94d8169f..ec1499e861 100644 --- a/thirdparty/harfbuzz/src/hb-cairo-utils.cc +++ b/thirdparty/harfbuzz/src/hb-cairo-utils.cc @@ -80,7 +80,7 @@ hb_cairo_read_blob (void *closure, if (r->offset + length > size) return CAIRO_STATUS_READ_ERROR; - memcpy (data, d + r->offset, length); + hb_memcpy (data, d + r->offset, length); r->offset += length; return CAIRO_STATUS_SUCCESS; @@ -763,7 +763,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, } //assert (angles[0] + k * span <= 0 && 0 < angles[n_stops - 1] + k * span); - span = fabs (span); + span = fabsf (span); for (signed l = k; l < 1000; l++) { diff --git a/thirdparty/harfbuzz/src/hb-cairo.cc b/thirdparty/harfbuzz/src/hb-cairo.cc index f005afd17e..68c7bc064f 100644 --- a/thirdparty/harfbuzz/src/hb-cairo.cc +++ b/thirdparty/harfbuzz/src/hb-cairo.cc @@ -956,7 +956,7 @@ hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer, if (clusters && *num_clusters && utf8) { - memset ((void *) *clusters, 0, *num_clusters * sizeof ((*clusters)[0])); + hb_memset ((void *) *clusters, 0, *num_clusters * sizeof ((*clusters)[0])); hb_bool_t backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer)); *cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0; unsigned int cluster = 0; diff --git a/thirdparty/harfbuzz/src/hb-cff-interp-common.hh b/thirdparty/harfbuzz/src/hb-cff-interp-common.hh index 949bfebf9b..1d1f10f2bf 100644 --- a/thirdparty/harfbuzz/src/hb-cff-interp-common.hh +++ b/thirdparty/harfbuzz/src/hb-cff-interp-common.hh @@ -26,6 +26,8 @@ #ifndef HB_CFF_INTERP_COMMON_HH #define HB_CFF_INTERP_COMMON_HH +extern HB_INTERNAL const unsigned char *endchar_str; + namespace CFF { using namespace OT; @@ -336,8 +338,6 @@ struct byte_str_ref_t hb_ubytes_t str; }; -using byte_str_array_t = hb_vector_t<hb_ubytes_t>; - /* stack */ template <typename ELEM, int LIMIT> struct cff_stack_t diff --git a/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh b/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh index f40be51f0d..28a777eb0d 100644 --- a/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh +++ b/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh @@ -883,14 +883,12 @@ struct cs_interpreter_t : interpreter_t<ENV> unsigned max_ops = HB_CFF_MAX_OPS; for (;;) { - if (unlikely (!--max_ops)) + OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param); + if (unlikely (SUPER::env.in_error () || !--max_ops)) { SUPER::env.set_error (); - break; - } - OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param); - if (unlikely (SUPER::env.in_error ())) return false; + } if (SUPER::env.is_endchar ()) break; } diff --git a/thirdparty/harfbuzz/src/hb-common.h b/thirdparty/harfbuzz/src/hb-common.h index a5da4e76a3..a9fe666b39 100644 --- a/thirdparty/harfbuzz/src/hb-common.h +++ b/thirdparty/harfbuzz/src/hb-common.h @@ -104,6 +104,16 @@ typedef int hb_bool_t; * **/ typedef uint32_t hb_codepoint_t; + +/** + * HB_CODEPOINT_INVALID: + * + * Unused #hb_codepoint_t value. + * + * Since: 8.0.0 + */ +#define HB_CODEPOINT_INVALID ((hb_codepoint_t) -1) + /** * hb_position_t: * diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh index 26f7cba83e..335c6976f6 100644 --- a/thirdparty/harfbuzz/src/hb-config.hh +++ b/thirdparty/harfbuzz/src/hb-config.hh @@ -113,7 +113,6 @@ /* Closure of options. */ #ifdef HB_NO_BORING_EXPANSION -#define HB_NO_AVAR2 #define HB_NO_BEYOND_64K #define HB_NO_CUBIC_GLYF #define HB_NO_VAR_COMPOSITES diff --git a/thirdparty/harfbuzz/src/hb-debug.hh b/thirdparty/harfbuzz/src/hb-debug.hh index 0ac4515fa8..6055fce962 100644 --- a/thirdparty/harfbuzz/src/hb-debug.hh +++ b/thirdparty/harfbuzz/src/hb-debug.hh @@ -389,6 +389,10 @@ struct hb_no_trace_t { #define HB_DEBUG_UNISCRIBE (HB_DEBUG+0) #endif +#ifndef HB_DEBUG_WASM +#define HB_DEBUG_WASM (HB_DEBUG+0) +#endif + /* * With tracing. */ diff --git a/thirdparty/harfbuzz/src/hb-deprecated.h b/thirdparty/harfbuzz/src/hb-deprecated.h index b032a941b2..9fcce6d9ac 100644 --- a/thirdparty/harfbuzz/src/hb-deprecated.h +++ b/thirdparty/harfbuzz/src/hb-deprecated.h @@ -255,6 +255,52 @@ HB_EXTERN hb_position_t hb_font_get_glyph_v_kerning (hb_font_t *font, hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph); + +/** + * hb_font_get_glyph_shape_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @draw_funcs: The draw functions to send the shape data to + * @draw_data: The data accompanying the draw functions + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: 4.0.0 + * Deprecated: 7.0.0: Use #hb_font_draw_glyph_func_t instead + **/ +typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data); + +/** + * hb_font_funcs_set_glyph_shape_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_font_get_glyph_shape_func_t, + * which is the same as #hb_font_draw_glyph_func_t. + * + * Since: 4.0.0 + * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead + **/ +HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_func) +HB_EXTERN void +hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_shape_func_t func, + void *user_data, hb_destroy_func_t destroy); + +HB_DEPRECATED_FOR (hb_font_draw_glyph) +HB_EXTERN void +hb_font_get_glyph_shape (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data); + + #endif diff --git a/thirdparty/harfbuzz/src/hb-draw.hh b/thirdparty/harfbuzz/src/hb-draw.hh index 768f51a875..25dee1261e 100644 --- a/thirdparty/harfbuzz/src/hb-draw.hh +++ b/thirdparty/harfbuzz/src/hb-draw.hh @@ -93,50 +93,57 @@ struct hb_draw_funcs_t !user_data ? nullptr : user_data->close_path); } - void move_to (void *draw_data, hb_draw_state_t &st, - float to_x, float to_y) + void + HB_ALWAYS_INLINE + move_to (void *draw_data, hb_draw_state_t &st, + float to_x, float to_y) { - if (st.path_open) close_path (draw_data, st); + if (unlikely (st.path_open)) close_path (draw_data, st); st.current_x = to_x; st.current_y = to_y; } - void line_to (void *draw_data, hb_draw_state_t &st, - float to_x, float to_y) + void + HB_ALWAYS_INLINE + line_to (void *draw_data, hb_draw_state_t &st, + float to_x, float to_y) { - if (!st.path_open) start_path (draw_data, st); + if (unlikely (!st.path_open)) start_path (draw_data, st); emit_line_to (draw_data, st, to_x, to_y); st.current_x = to_x; st.current_y = to_y; } void + HB_ALWAYS_INLINE quadratic_to (void *draw_data, hb_draw_state_t &st, float control_x, float control_y, float to_x, float to_y) { - if (!st.path_open) start_path (draw_data, st); + if (unlikely (!st.path_open)) start_path (draw_data, st); emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y); st.current_x = to_x; st.current_y = to_y; } void + HB_ALWAYS_INLINE cubic_to (void *draw_data, hb_draw_state_t &st, float control1_x, float control1_y, float control2_x, float control2_y, float to_x, float to_y) { - if (!st.path_open) start_path (draw_data, st); + if (unlikely (!st.path_open)) start_path (draw_data, st); emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); st.current_x = to_x; st.current_y = to_y; } void + HB_ALWAYS_INLINE close_path (void *draw_data, hb_draw_state_t &st) { - if (st.path_open) + if (likely (st.path_open)) { if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y)) emit_line_to (draw_data, st, st.path_start_x, st.path_start_y); @@ -168,6 +175,7 @@ struct hb_draw_session_t ~hb_draw_session_t () { close_path (); } + HB_ALWAYS_INLINE void move_to (float to_x, float to_y) { if (likely (not_slanted)) @@ -177,6 +185,7 @@ struct hb_draw_session_t funcs->move_to (draw_data, st, to_x + to_y * slant, to_y); } + HB_ALWAYS_INLINE void line_to (float to_x, float to_y) { if (likely (not_slanted)) @@ -187,6 +196,7 @@ struct hb_draw_session_t to_x + to_y * slant, to_y); } void + HB_ALWAYS_INLINE quadratic_to (float control_x, float control_y, float to_x, float to_y) { @@ -200,6 +210,7 @@ struct hb_draw_session_t to_x + to_y * slant, to_y); } void + HB_ALWAYS_INLINE cubic_to (float control1_x, float control1_y, float control2_x, float control2_y, float to_x, float to_y) @@ -215,6 +226,7 @@ struct hb_draw_session_t control2_x + control2_y * slant, control2_y, to_x + to_y * slant, to_y); } + HB_ALWAYS_INLINE void close_path () { funcs->close_path (draw_data, st); diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc index 688513112a..f062bfaf75 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -1389,6 +1389,7 @@ hb_font_get_glyph_from_name (hb_font_t *font, return font->get_glyph_from_name (name, len, glyph); } +#ifndef HB_DISABLE_DEPRECATED /** * hb_font_get_glyph_shape: * @font: #hb_font_t to work upon @@ -1410,6 +1411,7 @@ hb_font_get_glyph_shape (hb_font_t *font, { hb_font_draw_glyph (font, glyph, dfuncs, draw_data); } +#endif /** * hb_font_draw_glyph: @@ -2648,7 +2650,6 @@ hb_font_set_variations (hb_font_t *font, if (axes[axis_index].axisTag == tag) design_coords[axis_index] = v; } - font->face->table.avar->map_coords (normalized, coords_length); hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); @@ -2720,8 +2721,6 @@ hb_font_set_variation (hb_font_t *font, if (axes[axis_index].axisTag == tag) design_coords[axis_index] = value; - font->face->table.avar->map_coords (normalized, coords_length); - hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); @@ -3058,6 +3057,7 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, #endif +#ifndef HB_DISABLE_DEPRECATED void hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_shape_func_t func, @@ -3066,3 +3066,4 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, { hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); } +#endif diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h index f3b589bd0d..3c2355af2d 100644 --- a/thirdparty/harfbuzz/src/hb-font.h +++ b/thirdparty/harfbuzz/src/hb-font.h @@ -486,25 +486,6 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * void *user_data); /** - * hb_font_get_glyph_shape_func_t: - * @font: #hb_font_t to work upon - * @font_data: @font user data pointer - * @glyph: The glyph ID to query - * @draw_funcs: The draw functions to send the shape data to - * @draw_data: The data accompanying the draw functions - * @user_data: User data pointer passed by the caller - * - * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. - * - * Since: 4.0.0 - * Deprecated: 7.0.0: Use #hb_font_draw_glyph_func_t instead - **/ -typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data); - -/** * hb_font_draw_glyph_func_t: * @font: #hb_font_t to work upon * @font_data: @font user data pointer @@ -804,32 +785,13 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, void *user_data, hb_destroy_func_t destroy); /** - * hb_font_funcs_set_glyph_shape_func: - * @ffuncs: A font-function structure - * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign - * @user_data: Data to pass to @func - * @destroy: (nullable): The function to call when @user_data is not needed anymore - * - * Sets the implementation function for #hb_font_get_glyph_shape_func_t, - * which is the same as #hb_font_draw_glyph_func_t. - * - * Since: 4.0.0 - * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead - **/ -HB_EXTERN void -hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_shape_func_t func, - void *user_data, hb_destroy_func_t destroy); - -/** * hb_font_funcs_set_draw_glyph_func: * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * Sets the implementation function for #hb_font_draw_glyph_func_t, - * which is the same as #hb_font_get_glyph_shape_func_t. + * Sets the implementation function for #hb_font_draw_glyph_func_t. * * Since: 7.0.0 **/ @@ -935,11 +897,6 @@ hb_font_get_glyph_from_name (hb_font_t *font, hb_codepoint_t *glyph); HB_EXTERN void -hb_font_get_glyph_shape (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_funcs_t *dfuncs, void *draw_data); - -HB_EXTERN void hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_draw_funcs_t *dfuncs, void *draw_data); diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index 1105862fbc..6ca3f85465 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -114,7 +114,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; ft_font->cached_serial = (unsigned) -1; - ft_font->advance_cache.init (); + new (&ft_font->advance_cache) hb_ft_advance_cache_t; return ft_font; } diff --git a/thirdparty/harfbuzz/src/hb-gobject-structs.cc b/thirdparty/harfbuzz/src/hb-gobject-structs.cc index 332cc84888..d66de0b237 100644 --- a/thirdparty/harfbuzz/src/hb-gobject-structs.cc +++ b/thirdparty/harfbuzz/src/hb-gobject-structs.cc @@ -29,7 +29,7 @@ #ifdef HAVE_GOBJECT -/** +/* * SECTION:hb-gobject * @title: hb-gobject * @short_description: GObject integration support diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc index 9e068f8d84..7ea0386223 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -248,6 +248,21 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, gr_fref_set_feature_value (fref, features[i].value, feats); } + hb_direction_t direction = buffer->props.direction; + hb_direction_t horiz_dir = hb_script_get_horizontal_direction (buffer->props.script); + /* TODO vertical: + * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType + * Ogham fonts are supposed to be implemented BTT or not. Need to research that + * first. */ + if ((HB_DIRECTION_IS_HORIZONTAL (direction) && + direction != horiz_dir && horiz_dir != HB_DIRECTION_INVALID) || + (HB_DIRECTION_IS_VERTICAL (direction) && + direction != HB_DIRECTION_TTB)) + { + hb_buffer_reverse_clusters (buffer); + direction = HB_DIRECTION_REVERSE (direction); + } + gr_segment *seg = nullptr; const gr_slot *is; unsigned int ci = 0, ic = 0; @@ -261,21 +276,11 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, for (unsigned int i = 0; i < buffer->len; ++i) chars[i] = buffer->info[i].codepoint; - /* TODO ensure_native_direction. */ - - hb_tag_t script_tag[HB_OT_MAX_TAGS_PER_SCRIPT]; - unsigned int count = HB_OT_MAX_TAGS_PER_SCRIPT; - hb_ot_tags_from_script_and_language (hb_buffer_get_script (buffer), - HB_LANGUAGE_INVALID, - &count, - script_tag, - nullptr, nullptr); - seg = gr_make_seg (nullptr, grface, - count ? script_tag[count - 1] : HB_OT_TAG_DEFAULT_SCRIPT, + HB_TAG_NONE, // https://github.com/harfbuzz/harfbuzz/issues/3439#issuecomment-1442650148 feats, gr_utf32, chars, buffer->len, - 2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0)); + 2 | (direction == HB_DIRECTION_RTL ? 1 : 0)); if (unlikely (!seg)) { if (feats) gr_featureval_destroy (feats); @@ -327,7 +332,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, float yscale = (float) font->y_scale / upem; yscale *= yscale / xscale; unsigned int curradv = 0; - if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) + if (HB_DIRECTION_IS_BACKWARD (direction)) { curradv = gr_slot_origin_X(gr_seg_first_slot(seg)) * xscale; clusters[0].advance = gr_seg_advance_X(seg) * xscale - curradv; @@ -356,16 +361,17 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, c->num_chars = before - c->base_char; c->base_glyph = ic; c->num_glyphs = 0; - if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) + if (HB_DIRECTION_IS_BACKWARD (direction)) { c->advance = curradv - gr_slot_origin_X(is) * xscale; curradv -= c->advance; } else { + auto origin_X = gr_slot_origin_X (is) * xscale; c->advance = 0; - clusters[ci].advance += gr_slot_origin_X(is) * xscale - curradv; - curradv += clusters[ci].advance; + clusters[ci].advance += origin_X - curradv; + curradv = origin_X; } ci++; } @@ -375,7 +381,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, clusters[ci].num_chars = after + 1 - clusters[ci].base_char; } - if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) + if (HB_DIRECTION_IS_BACKWARD (direction)) clusters[ci].advance += curradv; else clusters[ci].advance += gr_seg_advance_X(seg) * xscale - curradv; @@ -397,7 +403,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, unsigned int currclus = UINT_MAX; const hb_glyph_info_t *info = buffer->info; hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, nullptr); - if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) + if (!HB_DIRECTION_IS_BACKWARD (direction)) { curradvx = 0; for (is = gr_seg_first_slot (seg); is; pPos++, ++info, is = gr_slot_next_in_segment (is)) diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index b123b2f27c..61e05180be 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -63,6 +63,7 @@ struct hb_iter_t static constexpr bool is_iterator = true; static constexpr bool is_random_access_iterator = false; static constexpr bool is_sorted_iterator = false; + static constexpr bool has_fast_len = false; // Should be checked in combination with is_random_access_iterator. private: /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ @@ -393,7 +394,7 @@ struct hb_map_iter_t : private: Iter it; - hb_reference_wrapper<Proj> f; + mutable hb_reference_wrapper<Proj> f; }; template <typename Proj, hb_function_sortedness_t Sorted> @@ -456,8 +457,8 @@ struct hb_filter_iter_t : private: Iter it; - hb_reference_wrapper<Pred> p; - hb_reference_wrapper<Proj> f; + mutable hb_reference_wrapper<Pred> p; + mutable hb_reference_wrapper<Proj> f; }; template <typename Pred, typename Proj> struct hb_filter_iter_factory_t @@ -841,7 +842,7 @@ struct template <typename Iterable, hb_requires (hb_is_iterable (Iterable))> auto operator () (Iterable&& it, unsigned count) const HB_AUTO_RETURN - ( hb_zip (hb_range (count), it) | hb_map (hb_second) ) + ( hb_zip (hb_range (count), it) | hb_map_retains_sorting (hb_second) ) /* Specialization arrays. */ diff --git a/thirdparty/harfbuzz/src/hb-kern.hh b/thirdparty/harfbuzz/src/hb-kern.hh index 9ea945caed..9ac744c9dd 100644 --- a/thirdparty/harfbuzz/src/hb-kern.hh +++ b/thirdparty/harfbuzz/src/hb-kern.hh @@ -53,7 +53,7 @@ struct hb_kern_machine_t return; buffer->unsafe_to_concat (); - OT::hb_ot_apply_context_t c (1, font, buffer); + OT::hb_ot_apply_context_t c (1, font, buffer, hb_blob_get_empty ()); c.set_lookup_mask (kern_mask); c.set_lookup_props (OT::LookupFlag::IgnoreMarks); auto &skippy_iter = c.iter_input; diff --git a/thirdparty/harfbuzz/src/hb-limits.hh b/thirdparty/harfbuzz/src/hb-limits.hh index 0f60e9e210..c503b30652 100644 --- a/thirdparty/harfbuzz/src/hb-limits.hh +++ b/thirdparty/harfbuzz/src/hb-limits.hh @@ -89,6 +89,10 @@ #endif +#ifndef HB_GLYF_VAR_COMPOSITE_MAX_AXES +#define HB_GLYF_VAR_COMPOSITE_MAX_AXES 4096 +#endif + #ifndef HB_GLYF_MAX_POINTS #define HB_GLYF_MAX_POINTS 20000 #endif diff --git a/thirdparty/harfbuzz/src/hb-machinery.hh b/thirdparty/harfbuzz/src/hb-machinery.hh index 1084725af2..cde1e99d6f 100644 --- a/thirdparty/harfbuzz/src/hb-machinery.hh +++ b/thirdparty/harfbuzz/src/hb-machinery.hh @@ -131,6 +131,10 @@ static inline Type& StructAfter(TObject &X) unsigned int get_size () const { return (size - (array).min_size + (array).get_size ()); } \ DEFINE_SIZE_ARRAY(size, array) +#define DEFINE_SIZE_MAX(size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) <= (size)) \ + static constexpr unsigned max_size = (size) + /* @@ -180,6 +184,9 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> hb_lazy_loader_t<Returned,Subclass,Data,WheresData,Stored> >::value Funcs; + hb_lazy_loader_t () = default; + hb_lazy_loader_t (const hb_lazy_loader_t &other) = delete; + void init0 () {} /* Init, when memory is already set to 0. No-op for us. */ void init () { instance.set_relaxed (nullptr); } void fini () { do_destroy (instance.get_acquire ()); init (); } @@ -278,7 +285,11 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> template <typename T, unsigned int WheresFace> struct hb_face_lazy_loader_t : hb_lazy_loader_t<T, hb_face_lazy_loader_t<T, WheresFace>, - hb_face_t, WheresFace> {}; + hb_face_t, WheresFace> +{ + // Hack; have them here for API parity with hb_table_lazy_loader_t + hb_blob_t *get_blob () { return this->get ()->get_blob (); } +}; template <typename T, unsigned int WheresFace, bool core=false> struct hb_table_lazy_loader_t : hb_lazy_loader_t<T, @@ -288,7 +299,7 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<T, { static hb_blob_t *create (hb_face_t *face) { - auto c = hb_sanitize_context_t (); + hb_sanitize_context_t c; if (core) c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs return c.reference_table<T> (face); diff --git a/thirdparty/harfbuzz/src/hb-map.h b/thirdparty/harfbuzz/src/hb-map.h index e928628fa7..0ae171714e 100644 --- a/thirdparty/harfbuzz/src/hb-map.h +++ b/thirdparty/harfbuzz/src/hb-map.h @@ -44,7 +44,7 @@ HB_BEGIN_DECLS * * Since: 1.7.7 */ -#define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1) +#define HB_MAP_VALUE_INVALID HB_CODEPOINT_INVALID /** * hb_map_t: diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh index c685a9a3e1..e8abeec636 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -45,9 +45,9 @@ struct hb_hashmap_t hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (o.population); hb_copy (o, *this); } + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { alloc (o.population); hb_copy (o, *this); } hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); } - hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); resize (o.population); hb_copy (o, *this); return *this; } + hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t () @@ -60,29 +60,28 @@ struct hb_hashmap_t hb_hashmap_t (const Iterable &o) : hb_hashmap_t () { auto iter = hb_iter (o); - if (iter.is_random_access_iterator) - resize (hb_len (iter)); + if (iter.is_random_access_iterator || iter.has_fast_len) + alloc (hb_len (iter)); hb_copy (iter, *this); } struct item_t { K key; - uint32_t hash : 30; + uint32_t is_real_ : 1; uint32_t is_used_ : 1; - uint32_t is_tombstone_ : 1; + uint32_t hash : 30; V value; item_t () : key (), + is_real_ (false), is_used_ (false), hash (0), - is_used_ (false), is_tombstone_ (false), value () {} bool is_used () const { return is_used_; } void set_used (bool is_used) { is_used_ = is_used; } - bool is_tombstone () const { return is_tombstone_; } - void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; } - bool is_real () const { return is_used_ && !is_tombstone_; } + void set_real (bool is_real) { is_real_ = is_real; } + bool is_real () const { return is_real_; } template <bool v = minus_one, hb_enable_if (v == false)> @@ -98,10 +97,15 @@ struct hb_hashmap_t bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); } bool operator == (const item_t &o) const { return *this == o.key; } hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); } - hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); } + hb_pair_t<const K &, V &> get_pair_ref() { return hb_pair_t<const K &, V &> (key, value); } uint32_t total_hash () const { return (hash * 31) + hb_hash (value); } + + static constexpr bool is_trivial = std::is_trivially_constructible<K>::value && + std::is_trivially_destructible<K>::value && + std::is_trivially_constructible<V>::value && + std::is_trivially_destructible<V>::value; }; hb_object_header_t header; @@ -110,6 +114,7 @@ struct hb_hashmap_t unsigned int occupancy; /* Including tombstones. */ unsigned int mask; unsigned int prime; + unsigned int max_chain_length; item_t *items; friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) @@ -123,6 +128,7 @@ struct hb_hashmap_t hb_swap (a.occupancy, b.occupancy); hb_swap (a.mask, b.mask); hb_swap (a.prime, b.prime); + hb_swap (a.max_chain_length, b.max_chain_length); hb_swap (a.items, b.items); } void init () @@ -133,16 +139,19 @@ struct hb_hashmap_t population = occupancy = 0; mask = 0; prime = 0; + max_chain_length = 0; items = nullptr; } void fini () { hb_object_fini (this); - if (likely (items)) { + if (likely (items)) + { unsigned size = mask + 1; - for (unsigned i = 0; i < size; i++) - items[i].~item_t (); + if (!item_t::is_trivial) + for (unsigned i = 0; i < size; i++) + items[i].~item_t (); hb_free (items); items = nullptr; } @@ -157,7 +166,7 @@ struct hb_hashmap_t bool in_error () const { return !successful; } - bool resize (unsigned new_population = 0) + bool alloc (unsigned new_population = 0) { if (unlikely (!successful)) return false; @@ -171,8 +180,11 @@ struct hb_hashmap_t successful = false; return false; } - for (auto &_ : hb_iter (new_items, new_size)) - new (&_) item_t (); + if (!item_t::is_trivial) + for (auto &_ : hb_iter (new_items, new_size)) + new (&_) item_t (); + else + hb_memset (new_items, 0, (size_t) new_size * sizeof (item_t)); unsigned int old_size = size (); item_t *old_items = items; @@ -181,6 +193,7 @@ struct hb_hashmap_t population = occupancy = 0; mask = new_size - 1; prime = prime_for (power); + max_chain_length = power * 2; items = new_items; /* Insert back old items. */ @@ -192,7 +205,8 @@ struct hb_hashmap_t old_items[i].hash, std::move (old_items[i].value)); } - old_items[i].~item_t (); + if (!item_t::is_trivial) + old_items[i].~item_t (); } hb_free (old_items); @@ -201,72 +215,124 @@ struct hb_hashmap_t } template <typename KK, typename VV> - bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false) + bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool overwrite = true) { if (unlikely (!successful)) return false; - if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false; - item_t &item = item_for_hash (key, hash); + if (unlikely ((occupancy + occupancy / 2) >= mask && !alloc ())) return false; + + hash &= 0x3FFFFFFF; // We only store lower 30bit of hash + unsigned int tombstone = (unsigned int) -1; + unsigned int i = hash % prime; + unsigned length = 0; + unsigned step = 0; + while (items[i].is_used ()) + { + if ((std::is_integral<K>::value || items[i].hash == hash) && + items[i] == key) + { + if (!overwrite) + return false; + else + break; + } + if (!items[i].is_real () && tombstone == (unsigned) -1) + tombstone = i; + i = (i + ++step) & mask; + length++; + } - if (is_delete && !(item == key)) - return true; /* Trying to delete non-existent key. */ + item_t &item = items[tombstone == (unsigned) -1 ? i : tombstone]; if (item.is_used ()) { occupancy--; - if (!item.is_tombstone ()) - population--; + population -= item.is_real (); } item.key = std::forward<KK> (key); item.value = std::forward<VV> (value); item.hash = hash; item.set_used (true); - item.set_tombstone (is_delete); + item.set_real (true); occupancy++; - if (!is_delete) - population++; + population++; + + if (unlikely (length > max_chain_length) && occupancy * 8 > mask) + alloc (mask - 8); // This ensures we jump to next larger size return true; } template <typename VV> - bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); } + bool set (const K &key, VV&& value, bool overwrite = true) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value), overwrite); } template <typename VV> - bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward<VV> (value)); } + bool set (K &&key, VV&& value, bool overwrite = true) + { + uint32_t hash = hb_hash (key); + return set_with_hash (std::move (key), hash, std::forward<VV> (value), overwrite); + } const V& get_with_hash (const K &key, uint32_t hash) const { - if (unlikely (!items)) return item_t::default_value (); - auto &item = item_for_hash (key, hash); - return item.is_real () && item == key ? item.value : item_t::default_value (); + if (!items) return item_t::default_value (); + auto *item = fetch_item (key, hb_hash (key)); + if (item) + return item->value; + return item_t::default_value (); } const V& get (const K &key) const { - if (unlikely (!items)) return item_t::default_value (); + if (!items) return item_t::default_value (); return get_with_hash (key, hb_hash (key)); } - void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); } + void del (const K &key) + { + if (!items) return; + auto *item = fetch_item (key, hb_hash (key)); + if (item) + { + item->set_real (false); + population--; + } + } /* Has interface. */ const V& operator [] (K k) const { return get (k); } template <typename VV=V> - bool has (K key, VV **vp = nullptr) const + bool has (const K &key, VV **vp = nullptr) const { - if (unlikely (!items)) - return false; - auto &item = item_for_hash (key, hb_hash (key)); - if (item.is_real () && item == key) + if (!items) return false; + auto *item = fetch_item (key, hb_hash (key)); + if (item) { - if (vp) *vp = std::addressof (item.value); + if (vp) *vp = std::addressof (item->value); return true; } - else - return false; + return false; + } + item_t *fetch_item (const K &key, uint32_t hash) const + { + hash &= 0x3FFFFFFF; // We only store lower 30bit of hash + unsigned int i = hash % prime; + unsigned step = 0; + while (items[i].is_used ()) + { + if ((std::is_integral<K>::value || items[i].hash == hash) && + items[i] == key) + { + if (items[i].is_real ()) + return &items[i]; + else + return nullptr; + } + i = (i + ++step) & mask; + } + return nullptr; } /* Projection. */ - V operator () (K k) const { return get (k); } + const V& operator () (K k) const { return get (k); } unsigned size () const { return mask ? mask + 1 : 0; } @@ -393,24 +459,6 @@ struct hb_hashmap_t hb_hashmap_t& operator << (const hb_pair_t<K&&, V&&>& v) { set (std::move (v.first), std::move (v.second)); return *this; } - item_t& item_for_hash (const K &key, uint32_t hash) const - { - hash &= 0x3FFFFFFF; // We only store lower 30bit of hash - unsigned int i = hash % prime; - unsigned int step = 0; - unsigned int tombstone = (unsigned) -1; - while (items[i].is_used ()) - { - if ((hb_is_same (K, hb_codepoint_t) || items[i].hash == hash) && - items[i] == key) - return items[i]; - if (tombstone == (unsigned) -1 && items[i].is_tombstone ()) - tombstone = i; - i = (i + ++step) & mask; - } - return items[tombstone == (unsigned) -1 ? i : tombstone]; - } - static unsigned int prime_for (unsigned int shift) { /* Following comment and table copied from glib. */ @@ -481,7 +529,7 @@ struct hb_map_t : hb_hashmap_t<hb_codepoint_t, hb_map_t (hb_map_t &&o) : hashmap (std::move ((hashmap &) o)) {} hb_map_t& operator= (const hb_map_t&) = default; hb_map_t& operator= (hb_map_t&&) = default; - hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {} + hb_map_t (std::initializer_list<hb_codepoint_pair_t> lst) : hashmap (lst) {} template <typename Iterable, hb_requires (hb_is_iterable (Iterable))> hb_map_t (const Iterable &o) : hashmap (o) {} diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh index 31aa7fa6f1..52ff4a8412 100644 --- a/thirdparty/harfbuzz/src/hb-meta.hh +++ b/thirdparty/harfbuzz/src/hb-meta.hh @@ -153,8 +153,8 @@ struct hb_reference_wrapper hb_reference_wrapper (T v) : v (v) {} bool operator == (const hb_reference_wrapper& o) const { return v == o.v; } bool operator != (const hb_reference_wrapper& o) const { return v != o.v; } - operator T () const { return v; } - T get () const { return v; } + operator T& () { return v; } + T& get () { return v; } T v; }; template <typename T> @@ -163,8 +163,8 @@ struct hb_reference_wrapper<T&> hb_reference_wrapper (T& v) : v (std::addressof (v)) {} bool operator == (const hb_reference_wrapper& o) const { return v == o.v; } bool operator != (const hb_reference_wrapper& o) const { return v != o.v; } - operator T& () const { return *v; } - T& get () const { return *v; } + operator T& () { return *v; } + T& get () { return *v; } T* v; }; diff --git a/thirdparty/harfbuzz/src/hb-multimap.hh b/thirdparty/harfbuzz/src/hb-multimap.hh index b4a8cc62a3..0184279c12 100644 --- a/thirdparty/harfbuzz/src/hb-multimap.hh +++ b/thirdparty/harfbuzz/src/hb-multimap.hh @@ -38,10 +38,10 @@ struct hb_multimap_t { void add (hb_codepoint_t k, hb_codepoint_t v) { - hb_codepoint_t *i; - if (multiples_indices.has (k, &i)) + hb_vector_t<hb_codepoint_t> *m; + if (multiples.has (k, &m)) { - multiples_values[*i].push (v); + m->push (v); return; } @@ -51,12 +51,7 @@ struct hb_multimap_t hb_codepoint_t old = *old_v; singulars.del (k); - multiples_indices.set (k, multiples_values.length); - auto *vec = multiples_values.push (); - - vec->push (old); - vec->push (v); - + multiples.set (k, hb_vector_t<hb_codepoint_t> {old, v}); return; } @@ -69,22 +64,31 @@ struct hb_multimap_t if (singulars.has (k, &v)) return hb_array (v, 1); - hb_codepoint_t *i; - if (multiples_indices.has (k, &i)) - return multiples_values[*i].as_array (); + hb_vector_t<hb_codepoint_t> *m; + if (multiples.has (k, &m)) + return m->as_array (); return hb_array_t<const hb_codepoint_t> (); } bool in_error () const { - return singulars.in_error () || multiples_indices.in_error () || multiples_values.in_error (); + if (singulars.in_error () || multiples.in_error ()) + return true; + for (const auto &m : multiples.values_ref ()) + if (m.in_error ()) + return true; + return false; + } + + void alloc (unsigned size) + { + singulars.alloc (size); } protected: hb_map_t singulars; - hb_map_t multiples_indices; - hb_vector_t<hb_vector_t<hb_codepoint_t>> multiples_values; + hb_hashmap_t<hb_codepoint_t, hb_vector_t<hb_codepoint_t>> multiples; }; diff --git a/thirdparty/harfbuzz/src/hb-null.hh b/thirdparty/harfbuzz/src/hb-null.hh index 3da2d75ef5..2982516283 100644 --- a/thirdparty/harfbuzz/src/hb-null.hh +++ b/thirdparty/harfbuzz/src/hb-null.hh @@ -49,6 +49,15 @@ using hb_has_min_size = _hb_has_min_size<T, void>; #define hb_has_min_size(T) hb_has_min_size<T>::value template <typename T, typename> +struct _hb_has_max_size : hb_false_type {}; +template <typename T> +struct _hb_has_max_size<T, hb_void_t<decltype (T::max_size)>> + : hb_true_type {}; +template <typename T> +using hb_has_max_size = _hb_has_max_size<T, void>; +#define hb_has_max_size(T) hb_has_max_size<T>::value + +template <typename T, typename> struct _hb_has_null_size : hb_false_type {}; template <typename T> struct _hb_has_null_size<T, hb_void_t<decltype (T::null_size)>> @@ -176,7 +185,7 @@ template <typename Type> static inline Type& Crap () { static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast<Type *> (_hb_CrapPool); - memcpy (obj, &Null (Type), sizeof (*obj)); + memcpy (obj, std::addressof (Null (Type)), sizeof (*obj)); return *obj; } template <typename QType> @@ -211,11 +220,11 @@ struct hb_nonnull_ptr_t T * operator = (T *v_) { return v = v_; } T * operator -> () const { return get (); } T & operator * () const { return *get (); } - T ** operator & () const { return &v; } + T ** operator & () const { return std::addressof (v); } /* Only auto-cast to const types. */ template <typename C> operator const C * () const { return get (); } operator const char * () const { return (const char *) get (); } - T * get () const { return v ? v : const_cast<T *> (&Null (T)); } + T * get () const { return v ? v : const_cast<T *> (std::addressof (Null (T))); } T * get_raw () const { return v; } private: diff --git a/thirdparty/harfbuzz/src/hb-open-file.hh b/thirdparty/harfbuzz/src/hb-open-file.hh index 13570a46e0..04f144a72c 100644 --- a/thirdparty/harfbuzz/src/hb-open-file.hh +++ b/thirdparty/harfbuzz/src/hb-open-file.hh @@ -131,7 +131,7 @@ typedef struct OpenTypeOffsetTable sfnt_version = sfnt_tag; /* Take space for numTables, searchRange, entrySelector, RangeShift * and the TableRecords themselves. */ - unsigned num_items = it.len (); + unsigned num_items = hb_len (it); if (unlikely (!tables.serialize (c, num_items))) return_trace (false); const char *dir_end = (const char *) c->head; @@ -145,7 +145,7 @@ typedef struct OpenTypeOffsetTable unsigned len = blob->length; /* Allocate room for the table and copy it. */ - char *start = (char *) c->allocate_size<void> (len); + char *start = (char *) c->allocate_size<void> (len, false); if (unlikely (!start)) return false; TableRecord &rec = tables.arrayZ[i]; diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index 4c9bfebcec..6d464a3535 100644 --- a/thirdparty/harfbuzz/src/hb-open-type.hh +++ b/thirdparty/harfbuzz/src/hb-open-type.hh @@ -312,6 +312,8 @@ struct _hb_has_null<Type, true> template <typename Type, typename OffsetType, bool has_null=true> struct OffsetTo : Offset<OffsetType, has_null> { + using target_t = Type; + // Make sure Type is not unbounded; works only for types that are fully defined at OffsetTo time. static_assert (has_null == false || (hb_has_null_size (Type) || !hb_has_min_size (Type)), ""); @@ -416,12 +418,15 @@ struct OffsetTo : Offset<OffsetType, has_null> { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); - if (unlikely (this->is_null ())) return_trace (true); + //if (unlikely (this->is_null ())) return_trace (true); if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false); return_trace (true); } template <typename ...Ts> +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const { TRACE_SANITIZE (this); @@ -462,24 +467,16 @@ struct UnsizedArrayOf HB_DELETE_CREATE_COPY_ASSIGN (UnsizedArrayOf); - const Type& operator [] (int i_) const + const Type& operator [] (unsigned int i) const { - unsigned int i = (unsigned int) i_; - const Type *p = &arrayZ[i]; - if (unlikely ((const void *) p < (const void *) arrayZ)) return Null (Type); /* Overflowed. */ - _hb_compiler_memory_r_barrier (); - return *p; + return arrayZ[i]; } - Type& operator [] (int i_) + Type& operator [] (unsigned int i) { - unsigned int i = (unsigned int) i_; - Type *p = &arrayZ[i]; - if (unlikely ((const void *) p < (const void *) arrayZ)) return Crap (Type); /* Overflowed. */ - _hb_compiler_memory_r_barrier (); - return *p; + return arrayZ[i]; } - unsigned int get_size (unsigned int len) const + static unsigned int get_size (unsigned int len) { return len * Type::static_size; } template <typename T> operator T * () { return arrayZ; } @@ -533,6 +530,7 @@ struct UnsizedArrayOf } template <typename ...Ts> + HB_ALWAYS_INLINE bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const { TRACE_SANITIZE (this); @@ -720,7 +718,32 @@ struct ArrayOf return_trace (out); } + /* Special-case ArrayOf Offset16To structs with a maximum size. */ + template <typename T = Type, + typename Base = void, + hb_enable_if (hb_has_max_size (typename T::target_t) && + sizeof (T) == 2)> + HB_ALWAYS_INLINE + bool sanitize (hb_sanitize_context_t *c, const Base *base) const + { + TRACE_SANITIZE (this); + + if (unlikely (!sanitize_shallow (c))) return_trace (false); + + unsigned max_len = 65536 + Type::target_t::max_size; + + if (unlikely (c->check_range_fast (base, max_len))) + return_trace (true); + + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (unlikely (!c->dispatch (arrayZ[i], base))) + return_trace (false); + return_trace (true); + } + template <typename ...Ts> + HB_ALWAYS_INLINE bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); @@ -736,7 +759,7 @@ struct ArrayOf bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && c->check_array (arrayZ, len)); + return_trace (len.sanitize (c) && c->check_array_sized (arrayZ, len, sizeof (LenType))); } public: @@ -797,7 +820,7 @@ template <typename Type> using List16OfOffset16To = List16OfOffsetTo<Type, HBUINT16>; /* An array starting at second element. */ -template <typename Type, typename LenType=HBUINT16> +template <typename Type, typename LenType> struct HeadlessArrayOf { static constexpr unsigned item_size = Type::static_size; @@ -861,6 +884,7 @@ struct HeadlessArrayOf } template <typename ...Ts> + HB_ALWAYS_INLINE bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); @@ -878,7 +902,7 @@ struct HeadlessArrayOf { TRACE_SANITIZE (this); return_trace (lenP1.sanitize (c) && - (!lenP1 || c->check_array (arrayZ, lenP1 - 1))); + (!lenP1 || c->check_array_sized (arrayZ, lenP1 - 1, sizeof (LenType)))); } public: @@ -887,6 +911,7 @@ struct HeadlessArrayOf public: DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; +template <typename Type> using HeadlessArray16Of = HeadlessArrayOf<Type, HBUINT16>; /* An array storing length-1. */ template <typename Type, typename LenType=HBUINT16> @@ -912,6 +937,7 @@ struct ArrayOfM1 { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } template <typename ...Ts> + HB_ALWAYS_INLINE bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); @@ -929,7 +955,7 @@ struct ArrayOfM1 { TRACE_SANITIZE (this); return_trace (lenM1.sanitize (c) && - (c->check_array (arrayZ, lenM1 + 1))); + (c->check_array_sized (arrayZ, lenM1 + 1, sizeof (LenType)))); } public: @@ -1096,6 +1122,7 @@ struct VarSizedBinSearchArrayOf { return header.static_size + header.nUnits * header.unitSize; } template <typename ...Ts> + HB_ALWAYS_INLINE bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); diff --git a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh index f22824fc69..a2f90c8f5e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh @@ -48,12 +48,24 @@ static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offs struct code_pair_t { - hb_codepoint_t code; + unsigned code; hb_codepoint_t glyph; }; + using str_buff_t = hb_vector_t<unsigned char>; using str_buff_vec_t = hb_vector_t<str_buff_t>; +using glyph_to_sid_map_t = hb_vector_t<code_pair_t>; + +struct length_f_t +{ + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + unsigned operator () (const Iterable &_) const { return hb_len (hb_iter (_)); } + + unsigned operator () (unsigned _) const { return _; } +} +HB_FUNCOBJ (length_f); /* CFF INDEX */ template <typename COUNT> @@ -62,42 +74,52 @@ struct CFFIndex unsigned int offset_array_size () const { return offSize * (count + 1); } - CFFIndex *copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - unsigned int size = get_size (); - CFFIndex *out = c->allocate_size<CFFIndex> (size, false); - if (likely (out)) - hb_memcpy (out, this, size); - return_trace (out); - } - template <typename Iterable, hb_requires (hb_is_iterable (Iterable))> bool serialize (hb_serialize_context_t *c, - const Iterable &iterable) + const Iterable &iterable, + const unsigned *p_data_size = nullptr) { TRACE_SERIALIZE (this); + unsigned data_size; + if (p_data_size) + data_size = *p_data_size; + else + total_size (iterable, &data_size); + auto it = hb_iter (iterable); - serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len)); + if (unlikely (!serialize_header (c, +it, data_size))) return_trace (false); + unsigned char *ret = c->allocate_size<unsigned char> (data_size, false); + if (unlikely (!ret)) return_trace (false); for (const auto &_ : +it) - hb_iter (_).copy (c); + { + unsigned len = _.length; + if (len <= 1) + { + if (!len) + continue; + *ret++ = *_.arrayZ; + continue; + } + hb_memcpy (ret, _.arrayZ, len); + ret += len; + } return_trace (true); } template <typename Iterator, hb_requires (hb_is_iterator (Iterator))> bool serialize_header (hb_serialize_context_t *c, - Iterator it) + Iterator it, + unsigned data_size) { TRACE_SERIALIZE (this); - unsigned total = + it | hb_reduce (hb_add, 0); - unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8; + unsigned off_size = (hb_bit_storage (data_size + 1) + 7) / 8; /* serialize CFFIndex header */ if (unlikely (!c->extend_min (this))) return_trace (false); - this->count = it.len (); + this->count = hb_len (it); if (!this->count) return_trace (true); if (unlikely (!c->extend (this->offSize))) return_trace (false); this->offSize = off_size; @@ -106,25 +128,88 @@ struct CFFIndex /* serialize indices */ unsigned int offset = 1; - unsigned int i = 0; - for (unsigned _ : +it) + if (HB_OPTIMIZE_SIZE_VAL) { - set_offset_at (i++, offset); - offset += _; + unsigned int i = 0; + for (const auto &_ : +it) + { + set_offset_at (i++, offset); + offset += length_f (_); + } + set_offset_at (i, offset); } - set_offset_at (i, offset); - + else + switch (off_size) + { + case 1: + { + HBUINT8 *p = (HBUINT8 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += length_f (_); + } + *p = offset; + } + break; + case 2: + { + HBUINT16 *p = (HBUINT16 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += length_f (_); + } + *p = offset; + } + break; + case 3: + { + HBUINT24 *p = (HBUINT24 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += length_f (_); + } + *p = offset; + } + break; + case 4: + { + HBUINT32 *p = (HBUINT32 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += length_f (_); + } + *p = offset; + } + break; + default: + break; + } + + assert (offset == data_size + 1); return_trace (true); } template <typename Iterable, hb_requires (hb_is_iterable (Iterable))> - static unsigned total_size (const Iterable &iterable) + static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr) { - auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len); - if (!it) return 0; + auto it = + hb_iter (iterable); + if (!it) + { + if (data_size) *data_size = 0; + return min_size; + } + + unsigned total = 0; + for (const auto &_ : +it) + total += length_f (_); + + if (data_size) *data_size = total; - unsigned total = + it | hb_reduce (hb_add, 0); unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8; return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total; @@ -133,13 +218,16 @@ struct CFFIndex void set_offset_at (unsigned int index, unsigned int offset) { assert (index <= count); - HBUINT8 *p = offsets + offSize * index + offSize; + unsigned int size = offSize; - for (; size; size--) + const HBUINT8 *p = offsets; + switch (size) { - --p; - *p = offset & 0xFF; - offset >>= 8; + case 1: ((HBUINT8 *) p)[index] = offset; break; + case 2: ((HBUINT16 *) p)[index] = offset; break; + case 3: ((HBUINT24 *) p)[index] = offset; break; + case 4: ((HBUINT32 *) p)[index] = offset; break; + default: return; } } @@ -149,37 +237,30 @@ struct CFFIndex assert (index <= count); unsigned int size = offSize; - const HBUINT8 *p = offsets + size * index; + const HBUINT8 *p = offsets; switch (size) { - case 1: return * (HBUINT8 *) p; - case 2: return * (HBUINT16 *) p; - case 3: return * (HBUINT24 *) p; - case 4: return * (HBUINT32 *) p; + case 1: return ((HBUINT8 *) p)[index]; + case 2: return ((HBUINT16 *) p)[index]; + case 3: return ((HBUINT24 *) p)[index]; + case 4: return ((HBUINT32 *) p)[index]; default: return 0; } } - unsigned int length_at (unsigned int index) const - { - unsigned offset0 = offset_at (index); - unsigned offset1 = offset_at (index + 1); - if (unlikely (offset1 < offset0 || offset1 > offset_at (count))) - return 0; - return offset1 - offset0; - } - const unsigned char *data_base () const - { return (const unsigned char *) this + min_size + offSize.static_size + offset_array_size (); } + { return (const unsigned char *) this + min_size + offSize.static_size - 1 + offset_array_size (); } public: hb_ubytes_t operator [] (unsigned int index) const { if (unlikely (index >= count)) return hb_ubytes_t (); _hb_compiler_memory_r_barrier (); - unsigned length = length_at (index); - if (unlikely (!length)) return hb_ubytes_t (); - return hb_ubytes_t (data_base () + offset_at (index) - 1, length); + unsigned offset0 = offset_at (index); + unsigned offset1 = offset_at (index + 1); + if (unlikely (offset1 < offset0 || offset1 > offset_at (count))) + return hb_ubytes_t (); + return hb_ubytes_t (data_base () + offset0, offset1 - offset0); } unsigned int get_size () const @@ -197,7 +278,7 @@ struct CFFIndex (count < count + 1u && c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 && c->check_array (offsets, offSize, count + 1u) && - c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count) - 1))))); + c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count)))))); } public: @@ -211,47 +292,6 @@ struct CFFIndex DEFINE_SIZE_MIN (COUNT::static_size); }; -template <typename COUNT, typename TYPE> -struct CFFIndexOf : CFFIndex<COUNT> -{ - template <typename DATA, typename PARAM1, typename PARAM2> - bool serialize (hb_serialize_context_t *c, - unsigned int offSize_, - const DATA *dataArray, - unsigned int dataArrayLen, - const hb_vector_t<unsigned int> &dataSizeArray, - const PARAM1 ¶m1, - const PARAM2 ¶m2) - { - TRACE_SERIALIZE (this); - /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (this))) return_trace (false); - this->count = dataArrayLen; - this->offSize = offSize_; - if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1), false))) - return_trace (false); - - /* serialize indices */ - unsigned int offset = 1; - unsigned int i = 0; - for (; i < dataArrayLen; i++) - { - this->set_offset_at (i, offset); - offset += dataSizeArray[i]; - } - this->set_offset_at (i, offset); - - /* serialize data */ - for (unsigned int i = 0; i < dataArrayLen; i++) - { - TYPE *dest = c->start_embed<TYPE> (); - if (unlikely (!dest || !dest->serialize (c, dataArray[i], param1, param2))) - return_trace (false); - } - return_trace (true); - } -}; - /* Top Dict, Font Dict, Private Dict */ struct Dict : UnsizedByteStr { @@ -327,7 +367,7 @@ struct table_info_t }; template <typename COUNT> -struct FDArray : CFFIndexOf<COUNT, FontDict> +struct FDArray : CFFIndex<COUNT> { template <typename DICTVAL, typename INFO, typename Iterator, typename OP_SERIALIZER> bool serialize (hb_serialize_context_t *c, @@ -338,7 +378,11 @@ struct FDArray : CFFIndexOf<COUNT, FontDict> /* serialize INDEX data */ hb_vector_t<unsigned> sizes; + if (it.is_random_access_iterator) + sizes.alloc (hb_len (it)); + c->push (); + char *data_base = c->head; + it | hb_map ([&] (const hb_pair_t<const DICTVAL&, const INFO&> &_) { @@ -348,10 +392,16 @@ struct FDArray : CFFIndexOf<COUNT, FontDict> }) | hb_sink (sizes) ; + unsigned data_size = c->head - data_base; c->pop_pack (false); + if (unlikely (sizes.in_error ())) return_trace (false); + + /* It just happens that the above is packed right after the header below. + * Such a hack. */ + /* serialize INDEX header */ - return_trace (CFFIndex<COUNT>::serialize_header (c, hb_iter (sizes))); + return_trace (CFFIndex<COUNT>::serialize_header (c, hb_iter (sizes), data_size)); } }; @@ -368,8 +418,11 @@ struct FDSelect0 { return_trace (true); } - hb_codepoint_t get_fd (hb_codepoint_t glyph) const - { return (hb_codepoint_t) fds[glyph]; } + unsigned get_fd (hb_codepoint_t glyph) const + { return fds[glyph]; } + + hb_pair_t<unsigned, hb_codepoint_t> get_fd_range (hb_codepoint_t glyph) const + { return {fds[glyph], glyph + 1}; } unsigned int get_size (unsigned int num_glyphs) const { return HBUINT8::static_size * num_glyphs; } @@ -427,12 +480,20 @@ struct FDSelect3_4 return +1; } - hb_codepoint_t get_fd (hb_codepoint_t glyph) const + unsigned get_fd (hb_codepoint_t glyph) const { auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range); return range ? range->fd : ranges[nRanges () - 1].fd; } + hb_pair_t<unsigned, hb_codepoint_t> get_fd_range (hb_codepoint_t glyph) const + { + auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range); + unsigned fd = range ? range->fd : ranges[nRanges () - 1].fd; + hb_codepoint_t end = range ? range[1].first : ranges[nRanges () - 1].first; + return {fd, end}; + } + GID_TYPE &nRanges () { return ranges.len; } GID_TYPE nRanges () const { return ranges.len; } GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); } @@ -469,7 +530,7 @@ struct FDSelect } } - hb_codepoint_t get_fd (hb_codepoint_t glyph) const + unsigned get_fd (hb_codepoint_t glyph) const { if (this == &Null (FDSelect)) return 0; @@ -480,6 +541,18 @@ struct FDSelect default:return 0; } } + /* Returns pair of fd and one after last glyph in range. */ + hb_pair_t<unsigned, hb_codepoint_t> get_fd_range (hb_codepoint_t glyph) const + { + if (this == &Null (FDSelect)) return {0, 1}; + + switch (format) + { + case 0: return u.format0.get_fd_range (glyph); + case 3: return u.format3.get_fd_range (glyph); + default:return {0, 1}; + } + } bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const { diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.cc b/thirdparty/harfbuzz/src/hb-ot-cff1-table.cc index 5040c74623..66df28aae1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.cc @@ -574,11 +574,11 @@ bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, h struct get_seac_param_t { - get_seac_param_t (const OT::cff1::accelerator_t *_cff) : cff (_cff) {} + get_seac_param_t (const OT::cff1::accelerator_subset_t *_cff) : cff (_cff) {} bool has_seac () const { return base && accent; } - const OT::cff1::accelerator_t *cff; + const OT::cff1::accelerator_subset_t *cff; hb_codepoint_t base = 0; hb_codepoint_t accent = 0; }; @@ -596,7 +596,7 @@ struct cff1_cs_opset_seac_t : cff1_cs_opset_t<cff1_cs_opset_seac_t, get_seac_par } }; -bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const +bool OT::cff1::accelerator_subset_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const { if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false; diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh index 4d0a965eee..3d658ac626 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh @@ -28,7 +28,7 @@ #define HB_OT_CFF1_TABLE_HH #include "hb-ot-cff-common.hh" -#include "hb-subset-cff1.hh" +#include "hb-subset-cff-common.hh" #include "hb-draw.hh" #include "hb-paint.hh" @@ -52,7 +52,6 @@ enum EncodingID { StandardEncoding = 0, ExpertEncoding = 1 }; enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 }; typedef CFFIndex<HBUINT16> CFF1Index; -template <typename Type> struct CFF1IndexOf : CFFIndexOf<HBUINT16, Type> {}; typedef CFFIndex<HBUINT16> CFF1Index; typedef CFF1Index CFF1CharStrings; @@ -110,6 +109,7 @@ struct Encoding1 { hb_codepoint_t get_code (hb_codepoint_t glyph) const { + /* TODO: Add cache like get_sid. */ assert (glyph > 0); glyph--; for (unsigned int i = 0; i < nRanges (); i++) @@ -173,11 +173,7 @@ struct Encoding bool serialize (hb_serialize_context_t *c, const Encoding &src) { TRACE_SERIALIZE (this); - unsigned int size = src.get_size (); - Encoding *dest = c->allocate_size<Encoding> (size); - if (unlikely (!dest)) return_trace (false); - hb_memcpy (dest, &src, size); - return_trace (true); + return_trace (c->embed (src)); } /* serialize a subset Encoding */ @@ -312,26 +308,29 @@ struct Encoding }; /* Charset */ -struct Charset0 { - bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const +struct Charset0 +{ + bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && sids[num_glyphs - 1].sanitize (c)); + if (num_charset_entries) *num_charset_entries = num_glyphs; + return_trace (sids.sanitize (c, num_glyphs - 1)); } hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const { if (unlikely (glyph >= num_glyphs)) return 0; - if (glyph == 0) + if (unlikely (glyph == 0)) return 0; else return sids[glyph - 1]; } - void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const + void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { + mapping->resize (num_glyphs, false); for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++) - mapping->set (gid, sids[gid - 1]); + mapping->arrayZ[gid] = {sids[gid - 1], gid}; } hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const @@ -347,13 +346,13 @@ struct Charset0 { return 0; } - unsigned int get_size (unsigned int num_glyphs) const + static unsigned int get_size (unsigned int num_glyphs) { assert (num_glyphs > 0); - return HBUINT16::static_size * (num_glyphs - 1); + return UnsizedArrayOf<HBUINT16>::get_size (num_glyphs - 1); } - HBUINT16 sids[HB_VAR_ARRAY]; + UnsizedArrayOf<HBUINT16> sids; DEFINE_SIZE_ARRAY(0, sids); }; @@ -374,38 +373,62 @@ struct Charset_Range { template <typename TYPE> struct Charset1_2 { - bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const + bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); num_glyphs--; - for (unsigned int i = 0; num_glyphs > 0; i++) + unsigned i; + for (i = 0; num_glyphs > 0; i++) { if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1))) return_trace (false); num_glyphs -= (ranges[i].nLeft + 1); } + if (num_charset_entries) + *num_charset_entries = i; return_trace (true); } - hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const + hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs, + code_pair_t *cache = nullptr) const { if (unlikely (glyph >= num_glyphs)) return 0; - if (glyph == 0) return 0; - glyph--; - for (unsigned int i = 0;; i++) + unsigned i; + hb_codepoint_t start_glyph; + if (cache && likely (cache->glyph <= glyph)) { - if (glyph <= ranges[i].nLeft) - return (hb_codepoint_t) ranges[i].first + glyph; - glyph -= (ranges[i].nLeft + 1); + i = cache->code; + start_glyph = cache->glyph; + } + else + { + if (unlikely (glyph == 0)) return 0; + i = 0; + start_glyph = 1; + } + glyph -= start_glyph; + for (;; i++) + { + unsigned count = ranges[i].nLeft; + if (glyph <= count) + { + if (cache) + *cache = {i, start_glyph}; + return ranges[i].first + glyph; + } + count++; + start_glyph += count; + glyph -= count; } return 0; } - void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const + void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { + mapping->resize (num_glyphs, false); hb_codepoint_t gid = 1; if (gid >= num_glyphs) return; @@ -413,8 +436,9 @@ struct Charset1_2 { { hb_codepoint_t sid = ranges[i].first; unsigned count = ranges[i].nLeft + 1; + unsigned last = gid + count; for (unsigned j = 0; j < count; j++) - mapping->set (gid++, sid++); + mapping->arrayZ[gid++] = {sid++, last - 1}; if (gid >= num_glyphs) break; @@ -439,21 +463,26 @@ struct Charset1_2 { unsigned int get_size (unsigned int num_glyphs) const { - unsigned int size = HBUINT8::static_size; - int glyph = (int)num_glyphs; + int glyph = (int) num_glyphs; + unsigned num_ranges = 0; assert (glyph > 0); glyph--; for (unsigned int i = 0; glyph > 0; i++) { glyph -= (ranges[i].nLeft + 1); - size += Charset_Range<TYPE>::static_size; + num_ranges++; } - return size; + return get_size_for_ranges (num_ranges); + } + + static unsigned int get_size_for_ranges (unsigned int num_ranges) + { + return UnsizedArrayOf<Charset_Range<TYPE> >::get_size (num_ranges); } - Charset_Range<TYPE> ranges[HB_VAR_ARRAY]; + UnsizedArrayOf<Charset_Range<TYPE>> ranges; DEFINE_SIZE_ARRAY (0, ranges); }; @@ -469,11 +498,7 @@ struct Charset bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs) { TRACE_SERIALIZE (this); - unsigned int size = src.get_size (num_glyphs); - Charset *dest = c->allocate_size<Charset> (size); - if (unlikely (!dest)) return_trace (false); - hb_memcpy (dest, &src, size); - return_trace (true); + return_trace (c->embed ((const char *) &src, src.get_size (num_glyphs))); } /* serialize a subset Charset */ @@ -490,13 +515,13 @@ struct Charset { case 0: { - Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1)); + Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::get_size (num_glyphs), false); if (unlikely (!fmt0)) return_trace (false); unsigned int glyph = 0; for (unsigned int i = 0; i < sid_ranges.length; i++) { - hb_codepoint_t sid = sid_ranges[i].code; - for (int left = (int)sid_ranges[i].glyph; left >= 0; left--) + hb_codepoint_t sid = sid_ranges.arrayZ[i].code; + for (int left = (int)sid_ranges.arrayZ[i].glyph; left >= 0; left--) fmt0->sids[glyph++] = sid++; } } @@ -504,29 +529,35 @@ struct Charset case 1: { - Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length); + Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::get_size_for_ranges (sid_ranges.length), false); if (unlikely (!fmt1)) return_trace (false); + hb_codepoint_t all_glyphs = 0; for (unsigned int i = 0; i < sid_ranges.length; i++) { - if (unlikely (!(sid_ranges[i].glyph <= 0xFF))) - return_trace (false); - fmt1->ranges[i].first = sid_ranges[i].code; - fmt1->ranges[i].nLeft = sid_ranges[i].glyph; + auto &_ = sid_ranges.arrayZ[i]; + all_glyphs |= _.glyph; + fmt1->ranges[i].first = _.code; + fmt1->ranges[i].nLeft = _.glyph; } + if (unlikely (!(all_glyphs <= 0xFF))) + return_trace (false); } break; case 2: { - Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length); + Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::get_size_for_ranges (sid_ranges.length), false); if (unlikely (!fmt2)) return_trace (false); + hb_codepoint_t all_glyphs = 0; for (unsigned int i = 0; i < sid_ranges.length; i++) { - if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF))) - return_trace (false); - fmt2->ranges[i].first = sid_ranges[i].code; - fmt2->ranges[i].nLeft = sid_ranges[i].glyph; + auto &_ = sid_ranges.arrayZ[i]; + all_glyphs |= _.glyph; + fmt2->ranges[i].first = _.code; + fmt2->ranges[i].nLeft = _.glyph; } + if (unlikely (!(all_glyphs <= 0xFFFF))) + return_trace (false); } break; @@ -545,18 +576,19 @@ struct Charset } } - hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs) const + hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs, + code_pair_t *cache = nullptr) const { switch (format) { case 0: return u.format0.get_sid (glyph, num_glyphs); - case 1: return u.format1.get_sid (glyph, num_glyphs); - case 2: return u.format2.get_sid (glyph, num_glyphs); + case 1: return u.format1.get_sid (glyph, num_glyphs, cache); + case 2: return u.format2.get_sid (glyph, num_glyphs, cache); default:return 0; } } - void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const + void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { switch (format) { @@ -578,7 +610,7 @@ struct Charset } } - bool sanitize (hb_sanitize_context_t *c) const + bool sanitize (hb_sanitize_context_t *c, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) @@ -586,9 +618,9 @@ struct Charset switch (format) { - case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ())); - case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ())); - case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ())); + case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs (), num_charset_entries)); default:return_trace (false); } } @@ -606,10 +638,10 @@ struct Charset struct CFF1StringIndex : CFF1Index { bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings, - const hb_inc_bimap_t &sidmap) + const hb_vector_t<unsigned> &sidmap) { TRACE_SERIALIZE (this); - if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0))) + if (unlikely ((strings.count == 0) || (sidmap.length == 0))) { if (unlikely (!c->extend_min (this->count))) return_trace (false); @@ -617,15 +649,13 @@ struct CFF1StringIndex : CFF1Index return_trace (true); } - byte_str_array_t bytesArray; - if (!bytesArray.resize (sidmap.get_population ())) - return_trace (false); - for (unsigned int i = 0; i < strings.count; i++) - { - hb_codepoint_t j = sidmap[i]; - if (j != HB_MAP_VALUE_INVALID) - bytesArray[j] = strings[i]; - } + if (unlikely (sidmap.in_error ())) return_trace (false); + + // Save this in a vector since serialize() iterates it twice. + hb_vector_t<hb_ubytes_t> bytesArray (+ hb_iter (sidmap) + | hb_map (strings)); + + if (unlikely (bytesArray.in_error ())) return_trace (false); bool result = CFF1Index::serialize (c, bytesArray); return_trace (result); @@ -932,7 +962,7 @@ struct cff1_private_dict_opset_t : dict_opset_t } }; -struct cff1_private_dict_opset_subset : dict_opset_t +struct cff1_private_dict_opset_subset_t : dict_opset_t { static void process_op (op_code_t op, num_interp_env_t& env, cff1_private_dict_values_subset_t& dictval) { @@ -978,7 +1008,7 @@ typedef dict_interpreter_t<cff1_top_dict_opset_t, cff1_top_dict_values_t, cff1_t typedef dict_interpreter_t<cff1_font_dict_opset_t, cff1_font_dict_values_t> cff1_font_dict_interpreter_t; typedef CFF1Index CFF1NameIndex; -typedef CFF1IndexOf<TopDict> CFF1TopDictIndex; +typedef CFF1Index CFF1TopDictIndex; struct cff1_font_dict_values_mod_t { @@ -1031,8 +1061,10 @@ struct cff1 template <typename PRIVOPSET, typename PRIVDICTVAL> struct accelerator_templ_t { - void init (hb_face_t *face) + accelerator_templ_t (hb_face_t *face) { + if (!face) return; + topDict.init (); fontDicts.init (); privateDicts.init (); @@ -1046,22 +1078,22 @@ struct cff1 const OT::cff1 *cff = this->blob->template as<OT::cff1> (); if (cff == &Null (OT::cff1)) - { fini (); return; } + goto fail; nameIndex = &cff->nameIndex (cff); if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc)) - { fini (); return; } + goto fail; topDictIndex = &StructAtOffset<CFF1TopDictIndex> (nameIndex, nameIndex->get_size ()); if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) - { fini (); return; } + goto fail; { /* parse top dict */ const hb_ubytes_t topDictStr = (*topDictIndex)[0]; - if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; } + if (unlikely (!topDictStr.sanitize (&sc))) goto fail; cff1_top_dict_interp_env_t env (topDictStr); cff1_top_dict_interpreter_t top_interp (env); - if (unlikely (!top_interp.interpret (topDict))) { fini (); return; } + if (unlikely (!top_interp.interpret (topDict))) goto fail; } if (is_predef_charset ()) @@ -1069,7 +1101,7 @@ struct cff1 else { charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset); - if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc))) { fini (); return; } + if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries))) goto fail; } fdCount = 1; @@ -1079,7 +1111,7 @@ struct cff1 fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset); if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) || (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) - { fini (); return; } + goto fail; fdCount = fdArray->count; } @@ -1092,36 +1124,36 @@ struct cff1 encoding = &Null (Encoding); if (is_CID ()) { - if (unlikely (charset == &Null (Charset))) { fini (); return; } + if (unlikely (charset == &Null (Charset))) goto fail; } else { if (!is_predef_encoding ()) { encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset); - if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; } + if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) goto fail; } } stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ()); if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) - { fini (); return; } + goto fail; globalSubrs = &StructAtOffset<CFF1Subrs> (stringIndex, stringIndex->get_size ()); if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) - { fini (); return; } + goto fail; charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset); if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) - { fini (); return; } + goto fail; num_glyphs = charStrings->count; if (num_glyphs != sc.get_num_glyphs ()) - { fini (); return; } + goto fail; if (unlikely (!privateDicts.resize (fdCount))) - { fini (); return; } + goto fail; for (unsigned int i = 0; i < fdCount; i++) privateDicts[i].init (); @@ -1131,27 +1163,27 @@ struct cff1 for (unsigned int i = 0; i < fdCount; i++) { hb_ubytes_t fontDictStr = (*fdArray)[i]; - if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; } + if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; cff1_font_dict_values_t *font; cff1_top_dict_interp_env_t env (fontDictStr); cff1_font_dict_interpreter_t font_interp (env); font = fontDicts.push (); - if (unlikely (fontDicts.in_error ())) { fini (); return; } + if (unlikely (fontDicts.in_error ())) goto fail; font->init (); - if (unlikely (!font_interp.interpret (*font))) { fini (); return; } + if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; } + if (unlikely (!privDictStr.sanitize (&sc))) goto fail; num_interp_env_t env2 (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env2); priv->init (); - if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; } + if (unlikely (!priv_interp.interpret (*priv))) goto fail; priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset); if (priv->localSubrs != &Null (CFF1Subrs) && unlikely (!priv->localSubrs->sanitize (&sc))) - { fini (); return; } + goto fail; } } else /* non-CID */ @@ -1160,20 +1192,25 @@ struct cff1 PRIVDICTVAL *priv = &privateDicts[0]; const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; } + if (unlikely (!privDictStr.sanitize (&sc))) goto fail; num_interp_env_t env (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env); priv->init (); - if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; } + if (unlikely (!priv_interp.interpret (*priv))) goto fail; priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset); if (priv->localSubrs != &Null (CFF1Subrs) && unlikely (!priv->localSubrs->sanitize (&sc))) - { fini (); return; } + goto fail; } - } - void fini () + return; + + fail: + _fini (); + } + ~accelerator_templ_t () { _fini (); } + void _fini () { sc.end_processing (); topDict.fini (); @@ -1183,6 +1220,8 @@ struct cff1 blob = nullptr; } + hb_blob_t *get_blob () const { return blob; } + bool is_valid () const { return blob; } bool is_CID () const { return topDict.is_CID (); } @@ -1203,13 +1242,14 @@ struct cff1 bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; } - hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const + hb_codepoint_t glyph_to_code (hb_codepoint_t glyph, + code_pair_t *glyph_to_sid_cache = nullptr) const { if (encoding != &Null (Encoding)) return encoding->get_code (glyph); else { - hb_codepoint_t sid = glyph_to_sid (glyph); + hb_codepoint_t sid = glyph_to_sid (glyph, glyph_to_sid_cache); if (sid == 0) return 0; hb_codepoint_t code = 0; switch (topDict.EncodingOffset) @@ -1227,12 +1267,14 @@ struct cff1 } } - hb_map_t *create_glyph_to_sid_map () const + glyph_to_sid_map_t *create_glyph_to_sid_map () const { if (charset != &Null (Charset)) { - hb_map_t *mapping = hb_map_create (); - mapping->set (0, 0); + auto *mapping = (glyph_to_sid_map_t *) hb_malloc (sizeof (glyph_to_sid_map_t)); + if (unlikely (!mapping)) return nullptr; + mapping = new (mapping) glyph_to_sid_map_t (); + mapping->push (code_pair_t {0, 1}); charset->collect_glyph_to_sid_map (mapping, num_glyphs); return mapping; } @@ -1240,10 +1282,11 @@ struct cff1 return nullptr; } - hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const + hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph, + code_pair_t *cache = nullptr) const { if (charset != &Null (Charset)) - return charset->get_sid (glyph, num_glyphs); + return charset->get_sid (glyph, num_glyphs, cache); else { hb_codepoint_t sid = 0; @@ -1312,19 +1355,17 @@ struct cff1 hb_vector_t<PRIVDICTVAL> privateDicts; unsigned int num_glyphs = 0; + unsigned int num_charset_entries = 0; }; struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> { - accelerator_t (hb_face_t *face) + accelerator_t (hb_face_t *face) : SUPER (face) { - SUPER::init (face); - glyph_names.set_relaxed (nullptr); if (!is_valid ()) return; if (is_CID ()) return; - } ~accelerator_t () { @@ -1334,8 +1375,6 @@ struct cff1 names->fini (); hb_free (names); } - - SUPER::fini (); } bool get_glyph_name (hb_codepoint_t glyph, @@ -1386,9 +1425,10 @@ struct cff1 /* TODO */ /* fill glyph names */ + code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID}; for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) { - hb_codepoint_t sid = glyph_to_sid (gid); + hb_codepoint_t sid = glyph_to_sid (gid, &glyph_to_sid_cache); gname_t gname; gname.sid = sid; if (sid < cff1_std_strings_length) @@ -1426,7 +1466,6 @@ struct cff1 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; - HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; private: @@ -1453,9 +1492,24 @@ struct cff1 typedef accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> SUPER; }; - struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> {}; + struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset_t, cff1_private_dict_values_subset_t> + { + accelerator_subset_t (hb_face_t *face) : SUPER (face) {} + ~accelerator_subset_t () + { + if (cff_accelerator) + cff_subset_accelerator_t::destroy (cff_accelerator); + } + + HB_INTERNAL bool subset (hb_subset_context_t *c) const; + HB_INTERNAL bool serialize (hb_serialize_context_t *c, + struct cff1_subset_plan &plan) const; + HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; + + mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr; - bool subset (hb_subset_context_t *c) const { return hb_subset_cff1 (c); } + typedef accelerator_templ_t<cff1_private_dict_opset_subset_t, cff1_private_dict_values_subset_t> SUPER; + }; protected: HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_code (hb_codepoint_t sid); @@ -1479,6 +1533,10 @@ struct cff1_accelerator_t : cff1::accelerator_t { cff1_accelerator_t (hb_face_t *face) : cff1::accelerator_t (face) {} }; +struct cff1_subset_accelerator_t : cff1::accelerator_subset_t { + cff1_subset_accelerator_t (hb_face_t *face) : cff1::accelerator_subset_t (face) {} +}; + } /* namespace OT */ #endif /* HB_OT_CFF1_TABLE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh index 2134d48660..9913cdad0c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh @@ -28,7 +28,7 @@ #define HB_OT_CFF2_TABLE_HH #include "hb-ot-cff-common.hh" -#include "hb-subset-cff2.hh" +#include "hb-subset-cff-common.hh" #include "hb-draw.hh" #include "hb-paint.hh" @@ -41,7 +41,6 @@ namespace CFF { #define HB_OT_TAG_CFF2 HB_TAG('C','F','F','2') typedef CFFIndex<HBUINT32> CFF2Index; -template <typename Type> struct CFF2IndexOf : CFFIndexOf<HBUINT32, Type> {}; typedef CFF2Index CFF2CharStrings; typedef Subrs<HBUINT32> CFF2Subrs; @@ -393,6 +392,8 @@ struct cff2 { accelerator_templ_t (hb_face_t *face) { + if (!face) return; + topDict.init (); fontDicts.init (); privateDicts.init (); @@ -464,7 +465,6 @@ struct cff2 goto fail; } - return; fail: @@ -481,11 +481,13 @@ struct cff2 blob = nullptr; } - hb_map_t *create_glyph_to_sid_map () const + hb_vector_t<uint16_t> *create_glyph_to_sid_map () const { return nullptr; } + hb_blob_t *get_blob () const { return blob; } + bool is_valid () const { return blob; } protected: @@ -518,9 +520,24 @@ struct cff2 HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; }; - typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t; + struct accelerator_subset_t : accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> + { + accelerator_subset_t (hb_face_t *face) : SUPER (face) {} + ~accelerator_subset_t () + { + if (cff_accelerator) + cff_subset_accelerator_t::destroy (cff_accelerator); + } - bool subset (hb_subset_context_t *c) const { return hb_subset_cff2 (c); } + HB_INTERNAL bool subset (hb_subset_context_t *c) const; + HB_INTERNAL bool serialize (hb_serialize_context_t *c, + struct cff2_subset_plan &plan, + hb_array_t<int> normalized_coords) const; + + mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr; + + typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> SUPER; + }; public: FixedVersion<HBUINT8> version; /* Version of CFF2 table. set to 0x0200u */ @@ -535,6 +552,10 @@ struct cff2_accelerator_t : cff2::accelerator_t { cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {} }; +struct cff2_subset_accelerator_t : cff2::accelerator_subset_t { + cff2_subset_accelerator_t (hb_face_t *face) : cff2::accelerator_subset_t (face) {} +}; + } /* namespace OT */ #endif /* HB_OT_CFF2_TABLE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh index cf5ccd53e9..30401b1926 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh @@ -277,10 +277,10 @@ struct CmapSubtableFormat4 } } writer(c); - writer.end_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount); - c->allocate_size<HBUINT16> (2); // padding - writer.start_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount); - writer.id_delta_ = c->allocate_size<HBINT16> (HBINT16::static_size * segcount); + writer.end_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount, false); + (void) c->allocate_size<HBUINT16> (2); // padding + writer.start_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount, false); + writer.id_delta_ = c->allocate_size<HBINT16> (HBINT16::static_size * segcount, false); if (unlikely (!writer.end_code_ || !writer.start_code_ || !writer.id_delta_)) return false; @@ -325,7 +325,7 @@ struct CmapSubtableFormat4 { auto format4_iter = + it - | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) + | hb_filter ([&] (const hb_codepoint_pair_t _) { return _.first <= 0xFFFF; }) ; @@ -335,7 +335,7 @@ struct CmapSubtableFormat4 if (unlikely (!c->extend_min (this))) return; this->format = 4; - hb_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> cp_to_gid { + hb_vector_t<hb_codepoint_pair_t> cp_to_gid { format4_iter }; @@ -757,8 +757,7 @@ struct CmapSubtableLongSegmented hb_codepoint_t gid = this->groups[i].glyphID; if (!gid) { - /* Intention is: if (hb_is_same (T, CmapSubtableFormat13)) continue; */ - if (! T::group_get_glyph (this->groups[i], end)) continue; + if (T::formatNumber == 13) continue; start++; gid++; } @@ -766,11 +765,13 @@ struct CmapSubtableLongSegmented if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs)) end = start + (hb_codepoint_t) num_glyphs - gid; + mapping->alloc (mapping->get_population () + end - start + 1); + for (unsigned cp = start; cp <= end; cp++) { unicodes->add (cp); mapping->set (cp, gid); - gid++; + gid += T::increment; } } } @@ -794,6 +795,9 @@ struct CmapSubtableLongSegmented struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> { + static constexpr int increment = 1; + static constexpr int formatNumber = 12; + static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u) { return likely (group.startCharCode <= group.endCharCode) ? @@ -866,6 +870,9 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13> { + static constexpr int increment = 0; + static constexpr int formatNumber = 13; + static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u HB_UNUSED) { return group.glyphID; } @@ -917,8 +924,7 @@ struct DefaultUVS : SortedArray32Of<UnicodeValueRange> DefaultUVS* copy (hb_serialize_context_t *c, const hb_set_t *unicodes) const { - DefaultUVS *out = c->start_embed<DefaultUVS> (); - if (unlikely (!out)) return nullptr; + auto *out = c->start_embed<DefaultUVS> (); auto snap = c->snapshot (); HBUINT32 len; @@ -931,8 +937,7 @@ struct DefaultUVS : SortedArray32Of<UnicodeValueRange> hb_codepoint_t start = HB_SET_VALUE_INVALID; hb_codepoint_t end = HB_SET_VALUE_INVALID; - for (hb_codepoint_t u = HB_SET_VALUE_INVALID; - unicodes->next (&u);) + for (auto u : *unicodes) { if (!as_array ().bsearch (u)) continue; @@ -1067,9 +1072,7 @@ struct NonDefaultUVS : SortedArray32Of<UVSMapping> const hb_set_t *glyphs_requested, const hb_map_t *glyph_map) const { - NonDefaultUVS *out = c->start_embed<NonDefaultUVS> (); - if (unlikely (!out)) return nullptr; - + auto *out = c->start_embed<NonDefaultUVS> (); auto it = + as_array () | hb_filter ([&] (const UVSMapping& _) @@ -1767,7 +1770,6 @@ struct cmap TRACE_SUBSET (this); cmap *cmap_prime = c->serializer->start_embed<cmap> (); - if (unlikely (!c->serializer->check_success (cmap_prime))) return_trace (false); auto encodingrec_iter = + hb_iter (encodingRecord) @@ -1798,7 +1800,7 @@ struct cmap auto it = + c->plan->unicode_to_new_gid_list.iter () - | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) + | hb_filter ([&] (const hb_codepoint_pair_t _) { return (_.second != HB_MAP_VALUE_INVALID); }) ; diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index c89a1954a9..b3677c6a4c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -38,8 +38,8 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" -#include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" +#include "hb-ot-cff1-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-post-table.hh" #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. @@ -98,7 +98,7 @@ _hb_ot_font_create (hb_font_t *font) { cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t)); if (unlikely (!cmap_cache)) goto out; - cmap_cache->init (); + new (cmap_cache) hb_ot_font_cmap_cache_t (); if (unlikely (!hb_face_set_user_data (font->face, &hb_ot_font_cmap_cache_user_data_key, cmap_cache, @@ -230,8 +230,8 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, use_cache = false; goto out; } + new (cache) hb_ot_font_advance_cache_t; - cache->init (); if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache))) { hb_free (cache); @@ -255,7 +255,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, { /* Use cache. */ if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords) { - ot_font->advance_cache->init (); + ot_font->advance_cache->clear (); ot_font->cached_coords_serial.set_release (font->serial_coords); } @@ -436,8 +436,8 @@ hb_ot_get_glyph_extents (hb_font_t *font, #endif if (ot_face->glyf->get_extents (font, glyph, extents)) return true; #ifndef HB_NO_OT_FONT_CFF - if (ot_face->cff1->get_extents (font, glyph, extents)) return true; if (ot_face->cff2->get_extents (font, glyph, extents)) return true; + if (ot_face->cff1->get_extents (font, glyph, extents)) return true; #endif return false; @@ -525,8 +525,8 @@ hb_ot_draw_glyph (hb_font_t *font, embolden ? &outline : draw_data, font->slant_xy); if (!font->face->table.glyf->get_path (font, glyph, draw_session)) #ifndef HB_NO_CFF - if (!font->face->table.cff1->get_path (font, glyph, draw_session)) if (!font->face->table.cff2->get_path (font, glyph, draw_session)) + if (!font->face->table.cff1->get_path (font, glyph, draw_session)) #endif {} } @@ -565,8 +565,8 @@ hb_ot_paint_glyph (hb_font_t *font, #endif if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; #ifndef HB_NO_CFF - if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; + if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; #endif } #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-hdmx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hdmx-table.hh index 3bfd75502a..cbcf6f5f22 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hdmx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hdmx-table.hh @@ -46,21 +46,23 @@ struct DeviceRecord template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> - bool serialize (hb_serialize_context_t *c, unsigned pixelSize, Iterator it) + bool serialize (hb_serialize_context_t *c, + unsigned pixelSize, + Iterator it, + const hb_vector_t<hb_codepoint_pair_t> new_to_old_gid_list, + unsigned num_glyphs) { TRACE_SERIALIZE (this); - unsigned length = it.len (); - - if (unlikely (!c->extend (this, length))) return_trace (false); + if (unlikely (!c->extend (this, num_glyphs))) return_trace (false); this->pixelSize = pixelSize; this->maxWidth = + it | hb_reduce (hb_max, 0u); - + it - | hb_sink (widthsZ.as_array (length)); + for (auto &_ : new_to_old_gid_list) + widthsZ[_.first] = *it++; return_trace (true); } @@ -89,7 +91,11 @@ struct hdmx template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> - bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it) + bool serialize (hb_serialize_context_t *c, + unsigned version, + Iterator it, + const hb_vector_t<hb_codepoint_pair_t> &new_to_old_gid_list, + unsigned num_glyphs) { TRACE_SERIALIZE (this); @@ -97,10 +103,10 @@ struct hdmx this->version = version; this->numRecords = it.len (); - this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0); + this->sizeDeviceRecord = DeviceRecord::get_size (num_glyphs); for (const hb_item_type<Iterator>& _ : +it) - c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second); + c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second, new_to_old_gid_list, num_glyphs); return_trace (c->successful ()); } @@ -110,31 +116,30 @@ struct hdmx { TRACE_SUBSET (this); - hdmx *hdmx_prime = c->serializer->start_embed <hdmx> (); - if (unlikely (!hdmx_prime)) return_trace (false); + auto *hdmx_prime = c->serializer->start_embed <hdmx> (); + unsigned num_input_glyphs = get_num_glyphs (); auto it = + hb_range ((unsigned) numRecords) - | hb_map ([c, this] (unsigned _) + | hb_map ([c, num_input_glyphs, this] (unsigned _) { const DeviceRecord *device_record = &StructAtOffset<DeviceRecord> (&firstDeviceRecord, _ * sizeDeviceRecord); auto row = - + hb_range (c->plan->num_output_glyphs ()) - | hb_map (c->plan->reverse_glyph_map) - | hb_map ([this, c, device_record] (hb_codepoint_t _) + + hb_iter (c->plan->new_to_old_gid_list) + | hb_map ([num_input_glyphs, device_record] (hb_codepoint_pair_t _) { - if (c->plan->is_empty_glyph (_)) - return Null (HBUINT8); - return device_record->widthsZ.as_array (get_num_glyphs ()) [_]; + return device_record->widthsZ.as_array (num_input_glyphs) [_.second]; }) ; return hb_pair ((unsigned) device_record->pixelSize, +row); }) ; - hdmx_prime->serialize (c->serializer, version, it); + hdmx_prime->serialize (c->serializer, version, it, + c->plan->new_to_old_gid_list, + c->plan->num_output_glyphs ()); return_trace (true); } diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh index 835a1a585e..fed6ca1c7a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh @@ -83,7 +83,7 @@ struct hmtxvmtx bool subset_update_header (hb_subset_context_t *c, unsigned int num_hmetrics, const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map, - const hb_map_t *bounds_map) const + const hb_vector_t<unsigned> &bounds_vec) const { hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (c->plan->source, H::tableTag); hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob); @@ -114,6 +114,7 @@ struct hmtxvmtx HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET, caretOffset); } + bool empty = true; int min_lsb = 0x7FFF; int min_rsb = 0x7FFF; int max_extent = -0x7FFF; @@ -125,9 +126,10 @@ struct hmtxvmtx int lsb = _.second.second; max_adv = hb_max (max_adv, adv); - if (bounds_map->has (gid)) + if (bounds_vec[gid] != 0xFFFFFFFF) { - unsigned bound_width = bounds_map->get (gid); + empty = false; + unsigned bound_width = bounds_vec[gid]; int rsb = adv - lsb - bound_width; int extent = lsb + bound_width; min_lsb = hb_min (min_lsb, lsb); @@ -137,7 +139,7 @@ struct hmtxvmtx } table->advanceMax = max_adv; - if (!bounds_map->is_empty ()) + if (!empty) { table->minLeadingBearing = min_lsb; table->minTrailingBearing = min_rsb; @@ -156,32 +158,31 @@ struct hmtxvmtx hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, Iterator it, - unsigned num_long_metrics) + const hb_vector_t<hb_codepoint_pair_t> new_to_old_gid_list, + unsigned num_long_metrics, + unsigned total_num_metrics) { - unsigned idx = 0; - for (auto _ : it) + LongMetric* long_metrics = c->allocate_size<LongMetric> (num_long_metrics * LongMetric::static_size); + FWORD* short_metrics = c->allocate_size<FWORD> ((total_num_metrics - num_long_metrics) * FWORD::static_size); + if (!long_metrics || !short_metrics) return; + + short_metrics -= num_long_metrics; + + for (auto _ : new_to_old_gid_list) { - if (idx < num_long_metrics) - { - LongMetric lm; - lm.advance = _.first; - lm.sb = _.second; - if (unlikely (!c->embed<LongMetric> (&lm))) return; - } - else if (idx < 0x10000u) + hb_codepoint_t gid = _.first; + auto mtx = *it++; + + if (gid < num_long_metrics) { - FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size); - if (unlikely (!sb)) return; - *sb = _.second; + LongMetric& lm = long_metrics[gid]; + lm.advance = mtx.first; + lm.sb = mtx.second; } + else if (gid < 0x10000u) + short_metrics[gid] = mtx.second; else - { - // TODO: This does not do tail optimization. - UFWORD *adv = c->allocate_size<UFWORD> (UFWORD::static_size); - if (unlikely (!adv)) return; - *adv = _.first; - } - idx++; + ((UFWORD*) short_metrics)[gid] = mtx.first; } } @@ -189,8 +190,7 @@ struct hmtxvmtx { TRACE_SUBSET (this); - T *table_prime = c->serializer->start_embed <T> (); - if (unlikely (!table_prime)) return_trace (false); + auto *table_prime = c->serializer->start_embed <T> (); accelerator_t _mtx (c->plan->source); unsigned num_long_metrics; @@ -209,31 +209,36 @@ struct hmtxvmtx } auto it = - + hb_range (c->plan->num_output_glyphs ()) - | hb_map ([c, &_mtx, mtx_map] (unsigned _) + + hb_iter (c->plan->new_to_old_gid_list) + | hb_map ([c, &_mtx, mtx_map] (hb_codepoint_pair_t _) { - if (!mtx_map->has (_)) + hb_codepoint_t new_gid = _.first; + hb_codepoint_t old_gid = _.second; + + hb_pair_t<unsigned, int> *v = nullptr; + if (!mtx_map->has (new_gid, &v)) { - hb_codepoint_t old_gid; - if (!c->plan->old_gid_for_new_gid (_, &old_gid)) - return hb_pair (0u, 0); int lsb = 0; if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb); return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); } - return mtx_map->get (_); + return *v; }) ; - table_prime->serialize (c->serializer, it, num_long_metrics); + table_prime->serialize (c->serializer, + it, + c->plan->new_to_old_gid_list, + num_long_metrics, + c->plan->num_output_glyphs ()); if (unlikely (c->serializer->in_error ())) return_trace (false); // Amend header num hmetrics if (unlikely (!subset_update_header (c, num_long_metrics, mtx_map, - T::is_horizontal ? &c->plan->bounds_width_map : &c->plan->bounds_height_map))) + T::is_horizontal ? c->plan->bounds_width_vec : c->plan->bounds_height_vec))) return_trace (false); return_trace (true); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh index 8179e5acd5..2b7e9e4b18 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh @@ -170,8 +170,8 @@ struct FeatMinMaxRecord { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - minCoord.sanitize (c, this) && - maxCoord.sanitize (c, this))); + minCoord.sanitize (c, base) && + maxCoord.sanitize (c, base))); } protected: @@ -187,7 +187,6 @@ struct FeatMinMaxRecord * of MinMax table (may be NULL) */ public: DEFINE_SIZE_STATIC (8); - }; struct MinMax @@ -274,7 +273,7 @@ struct BaseLangSysRecord { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - minMax.sanitize (c, this))); + minMax.sanitize (c, base))); } protected: @@ -297,7 +296,8 @@ struct BaseScript const BaseCoord &get_base_coord (int baseline_tag_index) const { return (this+baseValues).get_base_coord (baseline_tag_index); } - bool has_data () const { return baseValues; } + bool has_values () const { return baseValues; } + bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ } bool sanitize (hb_sanitize_context_t *c) const { @@ -383,7 +383,7 @@ struct Axis const BaseCoord **coord) const { const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag); - if (!base_script.has_data ()) + if (!base_script.has_values ()) { *coord = nullptr; return false; @@ -410,7 +410,7 @@ struct Axis const BaseCoord **max_coord) const { const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag); - if (!base_script.has_data ()) + if (!base_script.has_min_max ()) { *min_coord = *max_coord = nullptr; return false; @@ -425,8 +425,8 @@ struct Axis { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - (this+baseTagList).sanitize (c) && - (this+baseScriptList).sanitize (c))); + baseTagList.sanitize (c, this) && + baseScriptList.sanitize (c, this))); } protected: @@ -473,14 +473,13 @@ struct BASE return true; } - /* TODO: Expose this separately sometime? */ bool get_min_max (hb_font_t *font, hb_direction_t direction, hb_tag_t script_tag, hb_tag_t language_tag, hb_tag_t feature_tag, hb_position_t *min, - hb_position_t *max) + hb_position_t *max) const { const BaseCoord *min_coord, *max_coord; if (!get_axis (direction).get_min_max (script_tag, language_tag, feature_tag, diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 36f123b559..b3af128e02 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -55,19 +55,22 @@ static bool ClassDef_remap_and_serialize ( hb_serialize_context_t *c, const hb_set_t &klasses, bool use_class_zero, - hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */ + hb_sorted_vector_t<hb_codepoint_pair_t> &glyph_and_klass, /* IN/OUT */ hb_map_t *klass_map /*IN/OUT*/); struct hb_collect_feature_substitutes_with_var_context_t { const hb_map_t *axes_index_tag_map; - const hb_hashmap_t<hb_tag_t, int> *axes_location; + const hb_hashmap_t<hb_tag_t, Triple> *axes_location; hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *record_cond_idx_map; hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map; + bool& insert_catch_all_feature_variation_record; // not stored in subset_plan hb_set_t *feature_indices; bool apply; + bool variation_applied; + bool universal; unsigned cur_record_idx; hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> *conditionset_map; }; @@ -807,7 +810,7 @@ struct Feature { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->featureParams.serialize_subset (c, featureParams, this, tag); @@ -981,7 +984,7 @@ struct RecordListOfFeature : RecordListOf<Feature> { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + hb_enumerate (*this) | hb_filter (l->feature_index_map, hb_first) @@ -1078,7 +1081,7 @@ struct LangSys { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); const uint32_t *v; out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; @@ -1188,7 +1191,7 @@ struct Script return false; auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); bool defaultLang = false; if (has_default_lang_sys ()) @@ -1247,7 +1250,7 @@ struct RecordListOfScript : RecordListOf<Script> { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); for (auto _ : + hb_enumerate (*this)) { @@ -1367,7 +1370,7 @@ struct Lookup { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->lookupType = lookupType; out->lookupFlag = lookupFlag; @@ -1456,7 +1459,7 @@ struct LookupOffsetList : List16OfOffsetTo<TLookup, OffsetType> { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + hb_enumerate (*this) | hb_filter (l->lookup_index_map, hb_first) @@ -1482,7 +1485,7 @@ struct LookupOffsetList : List16OfOffsetTo<TLookup, OffsetType> static bool ClassDef_remap_and_serialize (hb_serialize_context_t *c, const hb_set_t &klasses, bool use_class_zero, - hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */ + hb_sorted_vector_t<hb_codepoint_pair_t> &glyph_and_klass, /* IN/OUT */ hb_map_t *klass_map /*IN/OUT*/) { if (!klass_map) @@ -1573,7 +1576,7 @@ struct ClassDefFormat1_3 TRACE_SUBSET (this); const hb_map_t &glyph_map = c->plan->glyph_map_gsub; - hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass; + hb_sorted_vector_t<hb_codepoint_pair_t> glyph_and_klass; hb_set_t orig_klasses; hb_codepoint_t start = startGlyph; @@ -1592,10 +1595,13 @@ struct ClassDefFormat1_3 orig_klasses.add (klass); } - unsigned glyph_count = glyph_filter - ? hb_len (hb_iter (glyph_map.keys()) | hb_filter (glyph_filter)) - : glyph_map.get_population (); - use_class_zero = use_class_zero && glyph_count <= glyph_and_klass.length; + if (use_class_zero) + { + unsigned glyph_count = glyph_filter + ? hb_len (hb_iter (glyph_map.keys()) | hb_filter (glyph_filter)) + : glyph_map.get_population (); + use_class_zero = glyph_count <= glyph_and_klass.length; + } if (!ClassDef_remap_and_serialize (c->serializer, orig_klasses, use_class_zero, @@ -1830,7 +1836,7 @@ struct ClassDefFormat2_4 const hb_map_t &glyph_map = c->plan->glyph_map_gsub; const hb_set_t &glyph_set = *c->plan->glyphset_gsub (); - hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass; + hb_sorted_vector_t<hb_codepoint_pair_t> glyph_and_klass; hb_set_t orig_klasses; if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2 @@ -1916,7 +1922,7 @@ struct ClassDefFormat2_4 { if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) { - for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + for (auto g : *glyphs) if (get_class (g)) return true; return false; @@ -1976,8 +1982,7 @@ struct ClassDefFormat2_4 unsigned count = rangeRecord.len; if (count > glyphs->get_population () * hb_bit_storage (count) * 8) { - for (hb_codepoint_t g = HB_SET_VALUE_INVALID; - glyphs->next (&g);) + for (auto g : *glyphs) { unsigned i; if (rangeRecord.as_array ().bfind (g, &i) && @@ -2377,7 +2382,7 @@ struct VarRegionList return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount)); } - bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_bimap_t ®ion_map) + bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_inc_bimap_t ®ion_map) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); @@ -2494,7 +2499,7 @@ struct VarData bool serialize (hb_serialize_context_t *c, const VarData *src, const hb_inc_bimap_t &inner_map, - const hb_bimap_t ®ion_map) + const hb_inc_bimap_t ®ion_map) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); @@ -2905,9 +2910,9 @@ struct VariationStore enum Cond_with_Var_flag_t { KEEP_COND_WITH_VAR = 0, - DROP_COND_WITH_VAR = 1, - DROP_RECORD_WITH_VAR = 2, - MEM_ERR_WITH_VAR = 3, + KEEP_RECORD_WITH_VAR = 1, + DROP_COND_WITH_VAR = 2, + DROP_RECORD_WITH_VAR = 3, }; struct ConditionFormat1 @@ -2940,29 +2945,42 @@ struct ConditionFormat1 hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex); - //axis not pinned, keep the condition - if (!c->axes_location->has (axis_tag)) + Triple axis_range (-1.f, 0.f, 1.f); + if (c->axes_location->has (axis_tag)) + axis_range = c->axes_location->get (axis_tag); + + int axis_min_val = axis_range.minimum; + int axis_default_val = axis_range.middle; + int axis_max_val = axis_range.maximum; + + int16_t filter_min_val = filterRangeMinValue.to_int (); + int16_t filter_max_val = filterRangeMaxValue.to_int (); + + if (axis_default_val < filter_min_val || + axis_default_val > filter_max_val) + c->apply = false; + + //condition not met, drop the entire record + if (axis_min_val > filter_max_val || axis_max_val < filter_min_val || + filter_min_val > filter_max_val) + return DROP_RECORD_WITH_VAR; + + //condition met and axis pinned, drop the condition + if (c->axes_location->has (axis_tag) && + c->axes_location->get (axis_tag).is_point ()) + return DROP_COND_WITH_VAR; + + if (filter_max_val != axis_max_val || filter_min_val != axis_min_val) { // add axisIndex->value into the hashmap so we can check if the record is // unique with variations - int16_t min_val = filterRangeMinValue.to_int (); - int16_t max_val = filterRangeMaxValue.to_int (); - hb_codepoint_t val = (max_val << 16) + min_val; + hb_codepoint_t val = (filter_max_val << 16) + filter_min_val; condition_map->set (axisIndex, val); return KEEP_COND_WITH_VAR; } - //axis pinned, check if condition is met - //TODO: add check for axis Ranges - int v = c->axes_location->get (axis_tag); - - //condition not met, drop the entire record - if (v < filterRangeMinValue.to_int () || v > filterRangeMaxValue.to_int ()) - return DROP_RECORD_WITH_VAR; - - //axis pinned and condition met, drop the condition - return DROP_COND_WITH_VAR; + return KEEP_RECORD_WITH_VAR; } bool evaluate (const int *coords, unsigned int coord_len) const @@ -3001,7 +3019,7 @@ struct Condition { switch (u.format) { case 1: return u.format1.keep_with_variations (c, condition_map); - default:return KEEP_COND_WITH_VAR; + default: c->apply = false; return KEEP_COND_WITH_VAR; } } @@ -3046,45 +3064,50 @@ struct ConditionSet return true; } - Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const + void keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const { hb_map_t *condition_map = hb_map_create (); - if (unlikely (!condition_map)) return MEM_ERR_WITH_VAR; + if (unlikely (!condition_map)) return; hb::shared_ptr<hb_map_t> p {condition_map}; hb_set_t *cond_set = hb_set_create (); - if (unlikely (!cond_set)) return MEM_ERR_WITH_VAR; + if (unlikely (!cond_set)) return; hb::shared_ptr<hb_set_t> s {cond_set}; + c->apply = true; + bool should_keep = false; unsigned num_kept_cond = 0, cond_idx = 0; for (const auto& offset : conditions) { Cond_with_Var_flag_t ret = (this+offset).keep_with_variations (c, condition_map); - // one condition is not met, drop the entire record + // condition is not met or condition out of range, drop the entire record if (ret == DROP_RECORD_WITH_VAR) - return DROP_RECORD_WITH_VAR; + return; - // axis not pinned, keep this condition if (ret == KEEP_COND_WITH_VAR) { + should_keep = true; cond_set->add (cond_idx); num_kept_cond++; } + + if (ret == KEEP_RECORD_WITH_VAR) + should_keep = true; + cond_idx++; } - // all conditions met - if (num_kept_cond == 0) return DROP_COND_WITH_VAR; + if (!should_keep) return; //check if condition_set is unique with variations if (c->conditionset_map->has (p)) //duplicate found, drop the entire record - return DROP_RECORD_WITH_VAR; + return; c->conditionset_map->set (p, 1); c->record_cond_idx_map->set (c->cur_record_idx, s); - - return KEEP_COND_WITH_VAR; + if (should_keep && num_kept_cond == 0) + c->universal = true; } bool subset (hb_subset_context_t *c, @@ -3289,12 +3312,11 @@ struct FeatureVariationRecord void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c, const void *base) const { - // ret == 1, all conditions met - if ((base+conditions).keep_with_variations (c) == DROP_COND_WITH_VAR && - c->apply) + (base+conditions).keep_with_variations (c); + if (c->apply && !c->variation_applied) { (base+substitutions).collect_feature_substitutes_with_variations (c); - c->apply = false; // set variations only once + c->variation_applied = true; // set variations only once } } @@ -3361,7 +3383,12 @@ struct FeatureVariations { c->cur_record_idx = i; varRecords[i].collect_feature_substitutes_with_variations (c, this); + if (c->universal) + break; } + if (c->variation_applied && !c->universal && + !c->record_cond_idx_map->is_empty ()) + c->insert_catch_all_feature_variation_record = true; } FeatureVariations* copy (hb_serialize_context_t *c) const diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index 8e5be92d12..e10adb78be 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -143,9 +143,12 @@ struct hb_closure_context_t : return active_glyphs_stack.tail (); } - hb_set_t& push_cur_active_glyphs () + hb_set_t* push_cur_active_glyphs () { - return *active_glyphs_stack.push (); + hb_set_t *s = active_glyphs_stack.push (); + if (unlikely (active_glyphs_stack.in_error ())) + return nullptr; + return s; } bool pop_cur_done_glyphs () @@ -427,6 +430,9 @@ struct hb_ot_apply_context_t : MATCH_MAYBE }; +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif may_match_t may_match (hb_glyph_info_t &info, hb_codepoint_t glyph_data) const { @@ -446,6 +452,9 @@ struct hb_ot_apply_context_t : SKIP_MAYBE }; +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif may_skip_t may_skip (const hb_ot_apply_context_t *c, const hb_glyph_info_t &info) const { @@ -516,6 +525,9 @@ struct hb_ot_apply_context_t : } #endif +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif void reset (unsigned int start_index_, unsigned int num_items_) { @@ -525,6 +537,9 @@ struct hb_ot_apply_context_t : matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); } +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif void reset_fast (unsigned int start_index_, unsigned int num_items_) { @@ -540,6 +555,9 @@ struct hb_ot_apply_context_t : } matcher_t::may_skip_t +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif may_skip (const hb_glyph_info_t &info) const { return matcher.may_skip (c, info); } @@ -549,6 +567,9 @@ struct hb_ot_apply_context_t : SKIP }; +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif match_t match (hb_glyph_info_t &info) { matcher_t::may_skip_t skip = matcher.may_skip (c, info); @@ -567,6 +588,9 @@ struct hb_ot_apply_context_t : return SKIP; } +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif bool next (unsigned *unsafe_to = nullptr) { assert (num_items > 0); @@ -600,6 +624,9 @@ struct hb_ot_apply_context_t : *unsafe_to = end; return false; } +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif bool prev (unsigned *unsafe_from = nullptr) { assert (num_items > 0); @@ -703,6 +730,7 @@ struct hb_ot_apply_context_t : hb_font_t *font; hb_face_t *face; hb_buffer_t *buffer; + hb_sanitize_context_t sanitizer; recurse_func_t recurse_func = nullptr; const GDEF &gdef; const GDEF::accelerator_t &gdef_accel; @@ -729,9 +757,11 @@ struct hb_ot_apply_context_t : hb_ot_apply_context_t (unsigned int table_index_, hb_font_t *font_, - hb_buffer_t *buffer_) : + hb_buffer_t *buffer_, + hb_blob_t *table_blob_) : table_index (table_index_), font (font_), face (font->face), buffer (buffer_), + sanitizer (table_blob_), gdef ( #ifndef HB_NO_OT_LAYOUT *face->table.GDEF->table @@ -808,6 +838,9 @@ struct hb_ot_apply_context_t : return true; } +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif bool check_glyph_property (const hb_glyph_info_t *info, unsigned int match_props) const { @@ -1213,14 +1246,17 @@ static inline bool would_match_input (hb_would_apply_context_t *c, return true; } template <typename HBUINT> -static inline bool match_input (hb_ot_apply_context_t *c, - unsigned int count, /* Including the first glyph (not matched) */ - const HBUINT input[], /* Array of input values--start with second glyph */ - match_func_t match_func, - const void *match_data, - unsigned int *end_position, - unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], - unsigned int *p_total_component_count = nullptr) +#ifndef HB_OPTIMIZE_SIZE +HB_ALWAYS_INLINE +#endif +static bool match_input (hb_ot_apply_context_t *c, + unsigned int count, /* Including the first glyph (not matched) */ + const HBUINT input[], /* Array of input values--start with second glyph */ + match_func_t match_func, + const void *match_data, + unsigned int *end_position, + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], + unsigned int *p_total_component_count = nullptr) { TRACE_APPLY (nullptr); @@ -1456,12 +1492,15 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, } template <typename HBUINT> -static inline bool match_backtrack (hb_ot_apply_context_t *c, - unsigned int count, - const HBUINT backtrack[], - match_func_t match_func, - const void *match_data, - unsigned int *match_start) +#ifndef HB_OPTIMIZE_SIZE +HB_ALWAYS_INLINE +#endif +static bool match_backtrack (hb_ot_apply_context_t *c, + unsigned int count, + const HBUINT backtrack[], + match_func_t match_func, + const void *match_data, + unsigned int *match_start) { TRACE_APPLY (nullptr); @@ -1485,13 +1524,16 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c, } template <typename HBUINT> -static inline bool match_lookahead (hb_ot_apply_context_t *c, - unsigned int count, - const HBUINT lookahead[], - match_func_t match_func, - const void *match_data, - unsigned int start_index, - unsigned int *end_index) +#ifndef HB_OPTIMIZE_SIZE +HB_ALWAYS_INLINE +#endif +static bool match_lookahead (hb_ot_apply_context_t *c, + unsigned int count, + const HBUINT lookahead[], + match_func_t match_func, + const void *match_data, + unsigned int start_index, + unsigned int *end_index) { TRACE_APPLY (nullptr); @@ -1615,10 +1657,13 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, } covered_seq_indicies.add (seqIndex); + hb_set_t *cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) + return; if (has_pos_glyphs) { - c->push_cur_active_glyphs () = std::move (pos_glyphs); + *cur_active_glyphs = std::move (pos_glyphs); } else { - c->push_cur_active_glyphs ().set (*c->glyphs); + *cur_active_glyphs = *c->glyphs; } unsigned endIndex = inputCount; @@ -2001,8 +2046,7 @@ struct Rule bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (inputCount.sanitize (c) && - lookupCount.sanitize (c) && + return_trace (c->check_struct (this) && c->check_range (inputZ.arrayZ, inputZ.item_size * (inputCount ? inputCount - 1 : 0) + LookupRecord::static_size * lookupCount)); @@ -2021,6 +2065,7 @@ struct Rule * design order */ public: DEFINE_SIZE_ARRAY (4, inputZ); + DEFINE_SIZE_MAX (65536 * (Types::HBUINT::static_size + LookupRecord::static_size)); }; template <typename Types> @@ -2168,8 +2213,9 @@ struct ContextFormat1_4 void closure (hb_closure_context_t *c) const { - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); - get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), *cur_active_glyphs); struct ContextClosureLookupContext lookup_context = { {intersects_glyph, intersected_glyph}, @@ -2338,9 +2384,10 @@ struct ContextFormat2_5 if (!(this+coverage).intersects (c->glyphs)) return; - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); + *cur_active_glyphs); const ClassDef &class_def = this+classDef; @@ -2583,10 +2630,10 @@ struct ContextFormat3 if (!(this+coverageZ[0]).intersects (c->glyphs)) return; - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); - + *cur_active_glyphs); const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); struct ContextClosureLookupContext lookup_context = { @@ -2687,14 +2734,14 @@ struct ContextFormat3 bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!c->check_struct (this)) return_trace (false); + if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int count = glyphCount; - if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */ - if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false); + if (unlikely (!count)) return_trace (false); /* We want to access coverageZ[0] freely. */ + if (unlikely (!c->check_array (coverageZ.arrayZ, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (!coverageZ[i].sanitize (c, this)) return_trace (false); + if (unlikely (!coverageZ[i].sanitize (c, this))) return_trace (false); const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); - return_trace (c->check_array (lookupRecord, lookupCount)); + return_trace (likely (c->check_array (lookupRecord, lookupCount))); } protected: @@ -3014,8 +3061,6 @@ struct ChainRule const hb_map_t *lookahead_map = nullptr) const { TRACE_SERIALIZE (this); - auto *out = c->start_embed (this); - if (unlikely (!out)) return_trace (false); const hb_map_t *mapping = backtrack_map; serialize_array (c, backtrack.len, + backtrack.iter () @@ -3077,13 +3122,14 @@ struct ChainRule bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!backtrack.sanitize (c)) return_trace (false); + /* Hyper-optimized sanitized because this is really hot. */ + if (unlikely (!backtrack.len.sanitize (c))) return_trace (false); const auto &input = StructAfter<decltype (inputX)> (backtrack); - if (!input.sanitize (c)) return_trace (false); + if (unlikely (!input.lenP1.sanitize (c))) return_trace (false); const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); - if (!lookahead.sanitize (c)) return_trace (false); + if (unlikely (!lookahead.len.sanitize (c))) return_trace (false); const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); - return_trace (lookup.sanitize (c)); + return_trace (likely (lookup.sanitize (c))); } protected: @@ -3091,7 +3137,7 @@ struct ChainRule backtrack; /* Array of backtracking values * (to be matched before the input * sequence) */ - HeadlessArrayOf<typename Types::HBUINT> + HeadlessArray16Of<typename Types::HBUINT> inputX; /* Array of input values (start with * second glyph) */ Array16Of<typename Types::HBUINT> @@ -3102,6 +3148,7 @@ struct ChainRule * design order) */ public: DEFINE_SIZE_MIN (8); + DEFINE_SIZE_MAX (65536 * (3 * Types::HBUINT::static_size + LookupRecord::static_size)); }; template <typename Types> @@ -3251,9 +3298,10 @@ struct ChainContextFormat1_4 void closure (hb_closure_context_t *c) const { - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); + *cur_active_glyphs); struct ChainContextClosureLookupContext lookup_context = { {intersects_glyph, intersected_glyph}, @@ -3423,10 +3471,10 @@ struct ChainContextFormat2_5 if (!(this+coverage).intersects (c->glyphs)) return; - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); - + *cur_active_glyphs); const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; @@ -3727,10 +3775,11 @@ struct ChainContextFormat3 if (!(this+input[0]).intersects (c->glyphs)) return; - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) + return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); - + *cur_active_glyphs); const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); @@ -3849,8 +3898,6 @@ struct ChainContextFormat3 { TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (this); - if (unlikely (!out)) return_trace (false); if (unlikely (!c->serializer->embed (this->format))) return_trace (false); if (!serialize_coverage_offsets (c, backtrack.iter (), this)) @@ -3877,14 +3924,14 @@ struct ChainContextFormat3 bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!backtrack.sanitize (c, this)) return_trace (false); + if (unlikely (!backtrack.sanitize (c, this))) return_trace (false); const auto &input = StructAfter<decltype (inputX)> (backtrack); - if (!input.sanitize (c, this)) return_trace (false); - if (!input.len) return_trace (false); /* To be consistent with Context. */ + if (unlikely (!input.sanitize (c, this))) return_trace (false); + if (unlikely (!input.len)) return_trace (false); /* To be consistent with Context. */ const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); - if (!lookahead.sanitize (c, this)) return_trace (false); + if (unlikely (!lookahead.sanitize (c, this))) return_trace (false); const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); - return_trace (lookup.sanitize (c)); + return_trace (likely (lookup.sanitize (c))); } protected: @@ -3974,7 +4021,7 @@ struct ExtensionFormat1 TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->format = format; out->extensionLookupType = extensionLookupType; @@ -4503,7 +4550,10 @@ struct GSUBGPOS { accelerator_t (hb_face_t *face) { - this->table = hb_sanitize_context_t ().reference_table<T> (face); + hb_sanitize_context_t sc; + sc.lazy_some_gpos = true; + this->table = sc.reference_table<T> (face); + if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face))) { hb_blob_destroy (this->table.get_blob ()); @@ -4528,6 +4578,8 @@ struct GSUBGPOS this->table.destroy (); } + hb_blob_t *get_blob () const { return table.get_blob (); } + hb_ot_layout_lookup_accelerator_t *get_accel (unsigned lookup_index) const { if (unlikely (lookup_index >= lookup_count)) return nullptr; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index c66ee8cfd0..020b8a6c82 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -1316,8 +1316,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face, hb_set_t feature_indexes; hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes); - for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID; - hb_set_next (&feature_indexes, &feature_index);) + for (auto feature_index : feature_indexes) g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes); g.feature_variation_collect_lookups (&feature_indexes, nullptr, lookup_indexes); @@ -1570,7 +1569,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, glyphs_length = glyphs->get_population (); if (lookups) { - for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);) + for (auto lookup_index : *lookups) gsub.get_lookup (lookup_index).closure (&c, lookup_index); } else @@ -1953,7 +1952,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, { const unsigned int table_index = proxy.table_index; unsigned int i = 0; - OT::hb_ot_apply_context_t c (table_index, font, buffer); + OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob ()); c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func<OT::hb_ot_apply_context_t>); for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++) @@ -2011,20 +2010,20 @@ void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, h { GSUBProxy proxy (font->face); if (buffer->messaging () && - !buffer->message (font, "start table GSUB")) return; + !buffer->message (font, "start table GSUB script tag '%c%c%c%c'", HB_UNTAG (chosen_script[0]))) return; apply (proxy, plan, font, buffer); if (buffer->messaging ()) - (void) buffer->message (font, "end table GSUB"); + (void) buffer->message (font, "end table GSUB script tag '%c%c%c%c'", HB_UNTAG (chosen_script[0])); } void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const { GPOSProxy proxy (font->face); if (buffer->messaging () && - !buffer->message (font, "start table GPOS")) return; + !buffer->message (font, "start table GPOS script tag '%c%c%c%c'", HB_UNTAG (chosen_script[1]))) return; apply (proxy, plan, font, buffer); if (buffer->messaging ()) - (void) buffer->message (font, "end table GPOS"); + (void) buffer->message (font, "end table GPOS script tag '%c%c%c%c'", HB_UNTAG (chosen_script[1])); } void @@ -2036,6 +2035,112 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, } #ifndef HB_NO_BASE + +static void +choose_base_tags (hb_script_t script, + hb_language_t language, + hb_tag_t *script_tag, + hb_tag_t *language_tag) +{ + hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT]; + unsigned script_count = ARRAY_LENGTH (script_tags); + + hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE]; + unsigned language_count = ARRAY_LENGTH (language_tags); + + hb_ot_tags_from_script_and_language (script, language, + &script_count, script_tags, + &language_count, language_tags); + + *script_tag = script_count ? script_tags[script_count - 1] : HB_OT_TAG_DEFAULT_SCRIPT; + *language_tag = language_count ? language_tags[language_count - 1] : HB_OT_TAG_DEFAULT_LANGUAGE; +} + +/** + * hb_ot_layout_get_font_extents: + * @font: a font + * @direction: text direction. + * @script_tag: script tag. + * @language_tag: language tag. + * @extents: (out) (nullable): font extents if found. + * + * Fetches script/language-specific font extents. These values are + * looked up in the `BASE` table's `MinMax` records. + * + * If no such extents are found, the default extents for the font are + * fetched. As such, the return value of this function can for the + * most part be ignored. Note that the per-script/language extents + * do not have a line-gap value, and the line-gap is set to zero in + * that case. + * + * Return value: `true` if found script/language-specific font extents. + * + * Since: 8.0.0 + **/ +hb_bool_t +hb_ot_layout_get_font_extents (hb_font_t *font, + hb_direction_t direction, + hb_tag_t script_tag, + hb_tag_t language_tag, + hb_font_extents_t *extents) +{ + hb_position_t min, max; + if (font->face->table.BASE->get_min_max (font, direction, script_tag, language_tag, HB_TAG_NONE, + &min, &max)) + { + if (extents) + { + extents->ascender = max; + extents->descender = min; + extents->line_gap = 0; + } + return true; + } + + hb_font_get_extents_for_direction (font, direction, extents); + return false; +} + +/** + * hb_ot_layout_get_font_extents2: + * @font: a font + * @direction: text direction. + * @script: script. + * @language: (nullable): language. + * @extents: (out) (nullable): font extents if found. + * + * Fetches script/language-specific font extents. These values are + * looked up in the `BASE` table's `MinMax` records. + * + * If no such extents are found, the default extents for the font are + * fetched. As such, the return value of this function can for the + * most part be ignored. Note that the per-script/language extents + * do not have a line-gap value, and the line-gap is set to zero in + * that case. + * + * This function is like hb_ot_layout_get_font_extents() but takes + * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t. + * + * Return value: `true` if found script/language-specific font extents. + * + * Since: 8.0.0 + **/ +hb_bool_t +hb_ot_layout_get_font_extents2 (hb_font_t *font, + hb_direction_t direction, + hb_script_t script, + hb_language_t language, + hb_font_extents_t *extents) +{ + hb_tag_t script_tag, language_tag; + choose_base_tags (script, language, &script_tag, &language_tag); + return hb_ot_layout_get_font_extents (font, + direction, + script_tag, + language_tag, + extents); +} + /** * hb_ot_layout_get_horizontal_baseline_tag_for_script: * @script: a script tag. @@ -2134,6 +2239,42 @@ hb_ot_layout_get_baseline (hb_font_t *font, } /** + * hb_ot_layout_get_baseline2: + * @font: a font + * @baseline_tag: a baseline tag + * @direction: text direction. + * @script: script. + * @language: (nullable): language, currently unused. + * @coord: (out) (nullable): baseline value if found. + * + * Fetches a baseline value from the face. + * + * This function is like hb_ot_layout_get_baseline() but takes + * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t. + * + * Return value: `true` if found baseline value in the font. + * + * Since: 8.0.0 + **/ +hb_bool_t +hb_ot_layout_get_baseline2 (hb_font_t *font, + hb_ot_layout_baseline_tag_t baseline_tag, + hb_direction_t direction, + hb_script_t script, + hb_language_t language, + hb_position_t *coord /* OUT. May be NULL. */) +{ + hb_tag_t script_tag, language_tag; + choose_base_tags (script, language, &script_tag, &language_tag); + return hb_ot_layout_get_baseline (font, + baseline_tag, + direction, + script_tag, + language_tag, + coord); +} + +/** * hb_ot_layout_get_baseline_with_fallback: * @font: a font * @baseline_tag: a baseline tag @@ -2355,6 +2496,41 @@ hb_ot_layout_get_baseline_with_fallback (hb_font_t *font, } } +/** + * hb_ot_layout_get_baseline_with_fallback2: + * @font: a font + * @baseline_tag: a baseline tag + * @direction: text direction. + * @script: script. + * @language: (nullable): language, currently unused. + * @coord: (out): baseline value if found. + * + * Fetches a baseline value from the face, and synthesizes + * it if the font does not have it. + * + * This function is like hb_ot_layout_get_baseline_with_fallback() but takes + * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t. + * + * Since: 8.0.0 + **/ +void +hb_ot_layout_get_baseline_with_fallback2 (hb_font_t *font, + hb_ot_layout_baseline_tag_t baseline_tag, + hb_direction_t direction, + hb_script_t script, + hb_language_t language, + hb_position_t *coord /* OUT */) +{ + hb_tag_t script_tag, language_tag; + choose_base_tags (script, language, &script_tag, &language_tag); + hb_ot_layout_get_baseline_with_fallback (font, + baseline_tag, + direction, + script_tag, + language_tag, + coord); +} + #endif @@ -2451,9 +2627,10 @@ hb_ot_layout_lookup_get_optical_bound (hb_font_t *font, hb_codepoint_t glyph) { const OT::PosLookup &lookup = font->face->table.GPOS->table->get_lookup (lookup_index); + hb_blob_t *blob = font->face->table.GPOS->get_blob (); hb_glyph_position_t pos = {0}; hb_position_single_dispatch_t c; - lookup.dispatch (&c, font, direction, glyph, pos); + lookup.dispatch (&c, font, blob, direction, glyph, pos); hb_position_t ret = 0; switch (direction) { diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.h b/thirdparty/harfbuzz/src/hb-ot-layout.h index 10dcc65ac0..b0fae3707f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.h +++ b/thirdparty/harfbuzz/src/hb-ot-layout.h @@ -447,6 +447,20 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, * BASE */ +HB_EXTERN hb_bool_t +hb_ot_layout_get_font_extents (hb_font_t *font, + hb_direction_t direction, + hb_tag_t script_tag, + hb_tag_t language_tag, + hb_font_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_ot_layout_get_font_extents2 (hb_font_t *font, + hb_direction_t direction, + hb_script_t script, + hb_language_t language, + hb_font_extents_t *extents); + /** * hb_ot_layout_baseline_tag_t: * @HB_OT_LAYOUT_BASELINE_TAG_ROMAN: The baseline used by alphabetic scripts such as Latin, Cyrillic and Greek. @@ -499,6 +513,14 @@ hb_ot_layout_get_baseline (hb_font_t *font, hb_tag_t language_tag, hb_position_t *coord /* OUT. May be NULL. */); +HB_EXTERN hb_bool_t +hb_ot_layout_get_baseline2 (hb_font_t *font, + hb_ot_layout_baseline_tag_t baseline_tag, + hb_direction_t direction, + hb_script_t script, + hb_language_t language, + hb_position_t *coord /* OUT. May be NULL. */); + HB_EXTERN void hb_ot_layout_get_baseline_with_fallback (hb_font_t *font, hb_ot_layout_baseline_tag_t baseline_tag, @@ -507,6 +529,14 @@ hb_ot_layout_get_baseline_with_fallback (hb_font_t *font, hb_tag_t language_tag, hb_position_t *coord /* OUT */); +HB_EXTERN void +hb_ot_layout_get_baseline_with_fallback2 (hb_font_t *font, + hb_ot_layout_baseline_tag_t baseline_tag, + hb_direction_t direction, + hb_script_t script, + hb_language_t language, + hb_position_t *coord /* OUT */); + HB_END_DECLS #endif /* HB_OT_LAYOUT_H */ diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh index 9505d5f147..d71889331d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -448,7 +448,7 @@ _hb_glyph_info_get_lig_id (const hb_glyph_info_t *info) static inline bool _hb_glyph_info_ligated_internal (const hb_glyph_info_t *info) { - return !!(info->lig_props() & IS_LIG_BASE); + return info->lig_props() & IS_LIG_BASE; } static inline unsigned int @@ -496,37 +496,37 @@ _hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info) static inline bool _hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info) { - return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH); + return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH; } static inline bool _hb_glyph_info_is_ligature (const hb_glyph_info_t *info) { - return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE); + return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; } static inline bool _hb_glyph_info_is_mark (const hb_glyph_info_t *info) { - return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK); + return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK; } static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info) { - return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED); + return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED; } static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info) { - return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED); + return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED; } static inline bool _hb_glyph_info_multiplied (const hb_glyph_info_t *info) { - return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); + return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED; } static inline bool diff --git a/thirdparty/harfbuzz/src/hb-ot-map.cc b/thirdparty/harfbuzz/src/hb-ot-map.cc index 8882dbaccb..bacd56ef3f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.cc +++ b/thirdparty/harfbuzz/src/hb-ot-map.cc @@ -213,7 +213,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, /* Sort features and merge duplicates */ if (feature_infos.length) { - feature_infos.qsort (); + if (!is_simple) + feature_infos.qsort (); auto *f = feature_infos.arrayZ; unsigned int j = 0; unsigned count = feature_infos.length; @@ -314,7 +315,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, map->needs_fallback = !found; } //feature_infos.shrink (0); /* Done with these */ - + if (is_simple) + m.features.qsort (); add_gsub_pause (nullptr); add_gpos_pause (nullptr); @@ -350,7 +352,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, } /* Sort lookups and merge duplicates */ - if (last_num_lookups < lookups.length) + if (last_num_lookups + 1 < lookups.length) { lookups.as_array ().sub_array (last_num_lookups, lookups.length - last_num_lookups).qsort (); diff --git a/thirdparty/harfbuzz/src/hb-ot-map.hh b/thirdparty/harfbuzz/src/hb-ot-map.hh index efc8cae96a..8af8129ceb 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.hh +++ b/thirdparty/harfbuzz/src/hb-ot-map.hh @@ -60,6 +60,13 @@ struct hb_ot_map_t int cmp (const hb_tag_t tag_) const { return tag_ < tag ? -1 : tag_ > tag ? 1 : 0; } + + HB_INTERNAL static int cmp (const void *pa, const void *pb) + { + const feature_map_t *a = (const feature_map_t *) pa; + const feature_map_t *b = (const feature_map_t *) pb; + return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; + } }; struct lookup_map_t { @@ -273,6 +280,7 @@ struct hb_ot_map_builder_t hb_face_t *face; hb_segment_properties_t props; + bool is_simple; hb_tag_t chosen_script[2]; bool found_script[2]; diff --git a/thirdparty/harfbuzz/src/hb-ot-math-table.hh b/thirdparty/harfbuzz/src/hb-ot-math-table.hh index dccf720f46..b11da464b2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-math-table.hh @@ -73,7 +73,6 @@ struct MathConstants { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); - if (unlikely (!out)) return_trace (nullptr); HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2); if (unlikely (!p)) return_trace (nullptr); @@ -310,7 +309,6 @@ struct MathKern { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); - if (unlikely (!out)) return_trace (nullptr); if (unlikely (!c->embed (heightCount))) return_trace (nullptr); @@ -572,6 +570,7 @@ struct MathGlyphInfo auto it = + hb_iter (this+extendedShapeCoverage) + | hb_take (c->plan->source->get_num_glyphs ()) | hb_filter (glyphset) | hb_map_retains_sorting (glyph_map) ; @@ -757,8 +756,6 @@ struct MathGlyphAssembly bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out)) return_trace (false); if (!c->serializer->copy (italicsCorrection, this)) return_trace (false); if (!c->serializer->copy<HBUINT16> (partRecords.len)) return_trace (false); @@ -945,13 +942,13 @@ struct MathVariants if (unlikely (!c->serializer->extend_min (out))) return_trace (false); if (!c->serializer->check_assign (out->minConnectorOverlap, minConnectorOverlap, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); - + hb_sorted_vector_t<hb_codepoint_t> new_vert_coverage; hb_sorted_vector_t<hb_codepoint_t> new_hori_coverage; hb_set_t indices; collect_coverage_and_indices (new_vert_coverage, vertGlyphCoverage, 0, vertGlyphCount, indices, glyphset, glyph_map); collect_coverage_and_indices (new_hori_coverage, horizGlyphCoverage, vertGlyphCount, vertGlyphCount + horizGlyphCount, indices, glyphset, glyph_map); - + if (!c->serializer->check_assign (out->vertGlyphCount, new_vert_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); if (!c->serializer->check_assign (out->horizGlyphCount, new_hori_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) @@ -963,10 +960,10 @@ struct MathVariants if (!o) return_trace (false); o->serialize_subset (c, glyphConstruction[i], this); } - + if (new_vert_coverage) out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ()); - + if (new_hori_coverage) out->horizGlyphCoverage.serialize_serialize (c->serializer, new_hori_coverage.iter ()); return_trace (true); diff --git a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh index 97d18b9d75..72cb662473 100644 --- a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh @@ -249,7 +249,7 @@ struct OS2 if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t')) && !c->plan->pinned_at_default) { - float weight_class = c->plan->user_axes_location.get (HB_TAG ('w','g','h','t')); + float weight_class = c->plan->user_axes_location.get (HB_TAG ('w','g','h','t')).middle; if (!c->serializer->check_assign (os2_prime->usWeightClass, roundf (hb_clamp (weight_class, 1.0f, 1000.0f)), HB_SERIALIZE_ERROR_INT_OVERFLOW)) @@ -259,7 +259,7 @@ struct OS2 if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h')) && !c->plan->pinned_at_default) { - float width = c->plan->user_axes_location.get (HB_TAG ('w','d','t','h')); + float width = c->plan->user_axes_location.get (HB_TAG ('w','d','t','h')).middle; if (!c->serializer->check_assign (os2_prime->usWidthClass, roundf (map_wdth_to_widthclass (width)), HB_SERIALIZE_ERROR_INT_OVERFLOW)) @@ -287,8 +287,7 @@ struct OS2 /* This block doesn't show up in profiles. If it ever did, * we can rewrite it to iterate over OS/2 ranges and use * set iteration to check if the range matches. */ - for (hb_codepoint_t cp = HB_SET_VALUE_INVALID; - codepoints->next (&cp);) + for (auto cp : *codepoints) { unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp); if (bit < 128) diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh index 951e6395d6..d44233610a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh @@ -79,6 +79,11 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const post::accelerator_t _post (c->plan->source); hb_hashmap_t<hb_bytes_t, uint32_t, true> glyph_name_to_new_index; + + old_new_index_map.alloc (num_glyphs); + old_gid_new_index_map.alloc (num_glyphs); + glyph_name_to_new_index.alloc (num_glyphs); + for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++) { hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); @@ -86,11 +91,12 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const unsigned new_index; const uint32_t *new_index2; - if (old_index <= 257) new_index = old_index; + if (old_index <= 257) + new_index = old_index; else if (old_new_index_map.has (old_index, &new_index2)) - { new_index = *new_index2; - } else { + else + { hb_bytes_t s = _post.find_glyph_name (old_gid); new_index = glyph_name_to_new_index.get (s); if (new_index == (unsigned)-1) diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table.hh b/thirdparty/harfbuzz/src/hb-ot-post-table.hh index 042fa611ad..761e49d119 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table.hh @@ -96,8 +96,7 @@ struct post bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - post *post_prime = c->serializer->start_embed<post> (); - if (unlikely (!post_prime)) return_trace (false); + auto *post_prime = c->serializer->start_embed<post> (); bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES; if (!serialize (c->serializer, glyph_names)) @@ -117,7 +116,7 @@ struct post if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t')) && !c->plan->pinned_at_default) { - float italic_angle = c->plan->user_axes_location.get (HB_TAG ('s','l','n','t')); + float italic_angle = c->plan->user_axes_location.get (HB_TAG ('s','l','n','t')).middle; italic_angle = hb_max (-90.f, hb_min (italic_angle, 90.f)); post_prime->italicAngle.set_float (italic_angle); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 3d207e0681..d84313f190 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -313,6 +313,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, { hb_ot_map_builder_t *map = &planner->map; + map->is_simple = true; + map->enable_feature (HB_TAG('r','v','r','n')); map->add_gsub_pause (nullptr); @@ -354,7 +356,10 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */ if (planner->shaper->collect_features) + { + map->is_simple = false; planner->shaper->collect_features (planner); + } map->enable_feature (HB_TAG ('B','u','z','z')); /* Considered required. */ map->enable_feature (HB_TAG ('B','U','Z','Z')); /* Considered discretionary. */ @@ -378,6 +383,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, map->enable_feature (HB_TAG ('v','e','r','t'), F_GLOBAL_SEARCH); } + if (num_user_features) + map->is_simple = false; for (unsigned int i = 0; i < num_user_features; i++) { const hb_feature_t *feature = &user_features[i]; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-fallback.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-fallback.hh index e7a69008b7..66a8bfbd28 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-fallback.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-fallback.hh @@ -368,7 +368,7 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan, hb_font_t *font, hb_buffer_t *buffer) { - OT::hb_ot_apply_context_t c (0, font, buffer); + OT::hb_ot_apply_context_t c (0, font, buffer, hb_blob_get_empty ()); for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) if (fallback_plan->lookup_array[i]) { c.set_lookup_mask (fallback_plan->mask_array[i]); diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh index 353e32d32c..7dd47755af 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh @@ -53,7 +53,7 @@ enum indic_syllable_type_t { }; -#line 57 "hb-ot-shaper-indic-machine.hh" +#line 54 "hb-ot-shaper-indic-machine.hh" #define indic_syllable_machine_ex_A 9u #define indic_syllable_machine_ex_C 1u #define indic_syllable_machine_ex_CM 16u @@ -76,7 +76,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 80 "hb-ot-shaper-indic-machine.hh" +#line 75 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { 8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, @@ -460,7 +460,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 464 "hb-ot-shaper-indic-machine.hh" +#line 453 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -476,7 +476,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 480 "hb-ot-shaper-indic-machine.hh" +#line 465 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -490,7 +490,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 494 "hb-ot-shaper-indic-machine.hh" +#line 477 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -593,7 +593,7 @@ _eof_trans: #line 114 "hb-ot-shaper-indic-machine.rl" {act = 6;} break; -#line 597 "hb-ot-shaper-indic-machine.hh" +#line 559 "hb-ot-shaper-indic-machine.hh" } _again: @@ -602,7 +602,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 606 "hb-ot-shaper-indic-machine.hh" +#line 566 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc index 89226ae4a1..97f62035c6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc @@ -40,6 +40,14 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) return false; if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE))) + { + if (buffer->messaging ()) + (void) buffer->message (font, "skipped inserting dotted-circles because there is no broken syllables"); + return false; + } + + if (buffer->messaging () && + !buffer->message (font, "start inserting dotted-circles")) return false; hb_codepoint_t dottedcircle_glyph; @@ -84,6 +92,10 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, (void) buffer->next_glyph (); } buffer->sync (); + + if (buffer->messaging ()) + (void) buffer->message (font, "end inserting dotted-circles"); + return true; } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc index 342aba1235..c35765af95 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc @@ -377,6 +377,9 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end) #define POST_BASE_FLAGS64 (FLAG64 (USE(FAbv)) | \ FLAG64 (USE(FBlw)) | \ FLAG64 (USE(FPst)) | \ + FLAG64 (USE(FMAbv)) | \ + FLAG64 (USE(FMBlw)) | \ + FLAG64 (USE(FMPst)) | \ FLAG64 (USE(MAbv)) | \ FLAG64 (USE(MBlw)) | \ FLAG64 (USE(MPst)) | \ diff --git a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh index de553dd72f..f7bb3791ca 100644 --- a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh @@ -57,6 +57,16 @@ enum // Reserved = 0xFFFC /* Reserved for future use — set to zero. */ }; +static bool axis_value_is_outside_axis_range (hb_tag_t axis_tag, float axis_value, + const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) +{ + if (!user_axes_location->has (axis_tag)) + return false; + + Triple axis_range = user_axes_location->get (axis_tag); + return (axis_value < axis_range.minimum || axis_value > axis_range.maximum); +} + struct StatAxisRecord { int cmp (hb_tag_t key) const { return tag.cmp (key); } @@ -96,23 +106,19 @@ struct AxisValueFormat1 } bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, - const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const { hb_tag_t axis_tag = get_axis_tag (axis_records); float axis_value = get_value (); - if (!user_axes_location->has (axis_tag) || - fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) - return true; - - return false; + return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location); } bool subset (hb_subset_context_t *c, const hb_array_t<const StatAxisRecord> axis_records) const { TRACE_SUBSET (this); - const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location; + const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location; if (keep_axis_value (axis_records, user_axes_location)) return_trace (c->serializer->embed (this)); @@ -155,23 +161,19 @@ struct AxisValueFormat2 } bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, - const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const { hb_tag_t axis_tag = get_axis_tag (axis_records); float axis_value = get_value (); - if (!user_axes_location->has (axis_tag) || - fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) - return true; - - return false; + return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location); } bool subset (hb_subset_context_t *c, const hb_array_t<const StatAxisRecord> axis_records) const { TRACE_SUBSET (this); - const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location; + const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location; if (keep_axis_value (axis_records, user_axes_location)) return_trace (c->serializer->embed (this)); @@ -218,23 +220,19 @@ struct AxisValueFormat3 } bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, - const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const { hb_tag_t axis_tag = get_axis_tag (axis_records); float axis_value = get_value (); - if (!user_axes_location->has (axis_tag) || - fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) - return true; - - return false; + return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location); } bool subset (hb_subset_context_t *c, const hb_array_t<const StatAxisRecord> axis_records) const { TRACE_SUBSET (this); - const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location; + const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location; if (keep_axis_value (axis_records, user_axes_location)) return_trace (c->serializer->embed (this)); @@ -291,7 +289,7 @@ struct AxisValueFormat4 { return axisValues.as_array (axisCount)[axis_index]; } bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, - const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const { hb_array_t<const AxisValueRecord> axis_value_records = axisValues.as_array (axisCount); @@ -301,8 +299,7 @@ struct AxisValueFormat4 float axis_value = rec.get_value (); hb_tag_t axis_tag = axis_records[axis_idx].get_axis_tag (); - if (user_axes_location->has (axis_tag) && - fabsf(axis_value - user_axes_location->get (axis_tag)) > 0.001f) + if (axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location)) return false; } @@ -313,7 +310,7 @@ struct AxisValueFormat4 const hb_array_t<const StatAxisRecord> axis_records) const { TRACE_SUBSET (this); - const hb_hashmap_t<hb_tag_t, float> *user_axes_location = &c->plan->user_axes_location; + const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location = &c->plan->user_axes_location; if (!keep_axis_value (axis_records, user_axes_location)) return_trace (false); @@ -402,7 +399,7 @@ struct AxisValue } bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, - hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const { switch (u.format) { @@ -451,8 +448,6 @@ struct AxisValueOffsetArray: UnsizedArrayOf<Offset16To<AxisValue>> const hb_array_t<const StatAxisRecord> axis_records) const { TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (this); - if (unlikely (!out)) return_trace (false); auto axisValueOffsets = as_array (axisValueCount); count = 0; @@ -517,7 +512,7 @@ struct STAT return axis_value.get_value_name_id (); } - void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location, + void collect_name_ids (hb_hashmap_t<hb_tag_t, Triple> *user_axes_location, hb_set_t *nameids_to_retain /* OUT */) const { if (!has_data ()) return; diff --git a/thirdparty/harfbuzz/src/hb-ot-tag.cc b/thirdparty/harfbuzz/src/hb-ot-tag.cc index 547f9573d0..53b6b38f66 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag.cc +++ b/thirdparty/harfbuzz/src/hb-ot-tag.cc @@ -412,7 +412,7 @@ parse_private_use_subtag (const char *private_use_subtag, /** * hb_ot_tags_from_script_and_language: * @script: an #hb_script_t to convert. - * @language: an #hb_language_t to convert. + * @language: (nullable): an #hb_language_t to convert. * @script_count: (inout) (optional): maximum number of script tags to retrieve (IN) * and actual number of script tags retrieved (OUT) * @script_tags: (out) (optional): array of size at least @script_count to store the diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh index 7d4bf2241c..44ec64bc03 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh @@ -36,19 +36,14 @@ struct DeltaSetIndexMapFormat01 { friend struct DeltaSetIndexMap; + unsigned get_size () const + { return min_size + mapCount * get_width (); } + private: DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); - auto *out = c->start_embed (this); - if (unlikely (!out)) return_trace (nullptr); - - unsigned total_size = min_size + mapCount * get_width (); - HBUINT8 *p = c->allocate_size<HBUINT8> (total_size); - if (unlikely (!p)) return_trace (nullptr); - - hb_memcpy (p, this, HBUINT8::static_size * total_size); - return_trace (out); + return_trace (c->embed (this)); } template <typename T> @@ -65,7 +60,7 @@ struct DeltaSetIndexMapFormat01 entryFormat = ((width-1)<<4)|(inner_bit_count-1); mapCount = output_map.length; - HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length); + HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length, false); if (unlikely (!p)) return_trace (false); for (unsigned int i = 0; i < output_map.length; i++) { @@ -242,6 +237,7 @@ struct VarStoreInstancer /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ struct TupleVariationHeader { + friend struct tuple_delta_t; unsigned get_size (unsigned axis_count) const { return min_size + get_all_tuples (axis_count).get_size (); } @@ -250,14 +246,67 @@ struct TupleVariationHeader const TupleVariationHeader &get_next (unsigned axis_count) const { return StructAtOffset<TupleVariationHeader> (this, get_size (axis_count)); } + bool unpack_axis_tuples (unsigned axis_count, + const hb_array_t<const F2DOT14> shared_tuples, + const hb_map_t *axes_old_index_tag_map, + hb_hashmap_t<hb_tag_t, Triple>& axis_tuples /* OUT */) const + { + const F2DOT14 *peak_tuple = nullptr; + if (has_peak ()) + peak_tuple = get_peak_tuple (axis_count).arrayZ; + else + { + unsigned int index = get_index (); + if (unlikely ((index + 1) * axis_count > shared_tuples.length)) + return false; + peak_tuple = shared_tuples.sub_array (axis_count * index, axis_count).arrayZ; + } + + const F2DOT14 *start_tuple = nullptr; + const F2DOT14 *end_tuple = nullptr; + bool has_interm = has_intermediate (); + + if (has_interm) + { + start_tuple = get_start_tuple (axis_count).arrayZ; + end_tuple = get_end_tuple (axis_count).arrayZ; + } + + for (unsigned i = 0; i < axis_count; i++) + { + float peak = peak_tuple[i].to_float (); + if (peak == 0.f) continue; + + hb_tag_t *axis_tag; + if (!axes_old_index_tag_map->has (i, &axis_tag)) + return false; + + float start, end; + if (has_interm) + { + start = start_tuple[i].to_float (); + end = end_tuple[i].to_float (); + } + else + { + start = hb_min (peak, 0.f); + end = hb_max (peak, 0.f); + } + axis_tuples.set (*axis_tag, Triple (start, peak, end)); + } + + return true; + } + float calculate_scalar (hb_array_t<int> coords, unsigned int coord_count, const hb_array_t<const F2DOT14> shared_tuples, - const hb_vector_t<int> *shared_tuple_active_idx = nullptr) const + const hb_vector_t<hb_pair_t<int,int>> *shared_tuple_active_idx = nullptr) const { const F2DOT14 *peak_tuple; unsigned start_idx = 0; unsigned end_idx = coord_count; + unsigned step = 1; if (has_peak ()) peak_tuple = get_peak_tuple (coord_count).arrayZ; @@ -272,10 +321,16 @@ struct TupleVariationHeader { if (unlikely (index >= shared_tuple_active_idx->length)) return 0.f; - int v = (*shared_tuple_active_idx).arrayZ[index]; - if (v != -1) + auto _ = (*shared_tuple_active_idx).arrayZ[index]; + if (_.second != -1) + { + start_idx = _.first; + end_idx = _.second + 1; + step = _.second - _.first; + } + else if (_.first != -1) { - start_idx = v; + start_idx = _.first; end_idx = start_idx + 1; } } @@ -291,7 +346,7 @@ struct TupleVariationHeader } float scalar = 1.f; - for (unsigned int i = start_idx; i < end_idx; i++) + for (unsigned int i = start_idx; i < end_idx; i += step) { int peak = peak_tuple[i].to_int (); if (!peak) continue; @@ -333,6 +388,7 @@ struct TupleVariationHeader TupleIndexMask = 0x0FFFu }; + TuppleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } DEFINE_SIZE_STATIC (2); }; @@ -365,6 +421,468 @@ struct TupleVariationHeader DEFINE_SIZE_MIN (4); }; +/* not using hb_bytes_t: avoid potential build issues with some compilers */ +struct byte_data_t +{ + hb_bytes_t bytes; + + byte_data_t () = default; + byte_data_t (const char *p_, unsigned len_) : bytes (hb_bytes_t (p_, len_)) {} + + void fini () { bytes.fini (); } + + bool operator == (const byte_data_t& o) const + { return bytes.arrayZ == o.bytes.arrayZ && bytes.length == o.bytes.length; } + + explicit operator bool () const { return bytes.length; } + + void copy (hb_serialize_context_t *c) const + { c->embed (bytes.arrayZ, bytes.length); } +}; + +enum packed_delta_flag_t +{ + DELTAS_ARE_ZERO = 0x80, + DELTAS_ARE_WORDS = 0x40, + DELTA_RUN_COUNT_MASK = 0x3F +}; + +struct tuple_delta_t +{ + public: + hb_hashmap_t<hb_tag_t, Triple> axis_tuples; + + /* indices_length = point_count, indice[i] = 1 means point i is referenced */ + hb_vector_t<bool> indices; + + hb_vector_t<float> deltas_x; + /* empty for cvar tuples */ + hb_vector_t<float> deltas_y; + + /* compiled data: header and deltas + * compiled point data is saved in a hashmap within tuple_variations_t cause + * some point sets might be reused by different tuple variations */ + hb_vector_t<char> compiled_tuple_header; + hb_vector_t<char> compiled_deltas; + + tuple_delta_t () = default; + tuple_delta_t (const tuple_delta_t& o) = default; + + tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + { + axis_tuples = std::move (o.axis_tuples); + indices = std::move (o.indices); + deltas_x = std::move (o.deltas_x); + deltas_y = std::move (o.deltas_y); + } + + tuple_delta_t& operator = (tuple_delta_t&& o) + { + hb_swap (*this, o); + return *this; + } + + void remove_axis (hb_tag_t axis_tag) + { axis_tuples.del (axis_tag); } + + bool set_tent (hb_tag_t axis_tag, Triple tent) + { return axis_tuples.set (axis_tag, tent); } + + tuple_delta_t& operator += (const tuple_delta_t& o) + { + unsigned num = indices.length; + for (unsigned i = 0; i < num; i++) + { + if (indices.arrayZ[i]) + { + if (o.indices.arrayZ[i]) + { + deltas_x[i] += o.deltas_x[i]; + if (deltas_y && o.deltas_y) + deltas_y[i] += o.deltas_y[i]; + } + } + else + { + if (!o.indices.arrayZ[i]) continue; + deltas_x[i] = o.deltas_x[i]; + if (deltas_y && o.deltas_y) + deltas_y[i] = o.deltas_y[i]; + } + } + return *this; + } + + tuple_delta_t& operator *= (float scalar) + { + if (scalar == 1.0f) + return *this; + + unsigned num = indices.length; + for (unsigned i = 0; i < num; i++) + { + if (!indices.arrayZ[i]) continue; + + deltas_x[i] *= scalar; + if (deltas_y) + deltas_y[i] *= scalar; + } + return *this; + } + + hb_vector_t<tuple_delta_t> change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit) const + { + hb_vector_t<tuple_delta_t> out; + Triple *tent; + if (!axis_tuples.has (axis_tag, &tent)) + { + out.push (*this); + return out; + } + + if ((tent->minimum < 0.f && tent->maximum > 0.f) || + !(tent->minimum <= tent->middle && tent->middle <= tent->maximum)) + return out; + + if (tent->middle == 0.f) + { + out.push (*this); + return out; + } + + result_t solutions = rebase_tent (*tent, axis_limit); + for (auto t : solutions) + { + tuple_delta_t new_var = *this; + if (t.second == Triple ()) + new_var.remove_axis (axis_tag); + else + new_var.set_tent (axis_tag, t.second); + + new_var *= t.first; + out.push (std::move (new_var)); + } + + return out; + } + + /* deltas should be compiled already before we compile tuple + * variation header cause we need to fill in the size of the + * serialized data for this tuple variation */ + //TODO(qxliu):add option to use sharedTuples in gvar + bool compile_tuple_var_header (const hb_map_t& axes_index_map, + unsigned points_data_length, + const hb_map_t& axes_old_index_tag_map) + { + if (!compiled_deltas) return false; + + unsigned cur_axis_count = axes_index_map.get_population (); + /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ + unsigned alloc_len = 3 * cur_axis_count * (F2DOT14::static_size) + 4; + if (unlikely (!compiled_tuple_header.resize (alloc_len))) return false; + + unsigned flag = 0; + /* skip the first 4 header bytes: variationDataSize+tupleIndex */ + F2DOT14* p = reinterpret_cast<F2DOT14 *> (compiled_tuple_header.begin () + 4); + F2DOT14* end = reinterpret_cast<F2DOT14 *> (compiled_tuple_header.end ()); + hb_array_t<F2DOT14> coords (p, end - p); + + /* encode peak coords */ + unsigned peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); + if (!peak_count) return false; + + /* encode interim coords, it's optional so returned num could be 0 */ + unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map); + + //TODO(qxliu): add option to use shared_points in gvar + flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers; + + unsigned serialized_data_size = points_data_length + compiled_deltas.length; + TupleVariationHeader *o = reinterpret_cast<TupleVariationHeader *> (compiled_tuple_header.begin ()); + o->varDataSize = serialized_data_size; + o->tupleIndex = flag; + + unsigned total_header_len = 4 + (peak_count + interim_count) * (F2DOT14::static_size); + return compiled_tuple_header.resize (total_header_len); + } + + unsigned encode_peak_coords (hb_array_t<F2DOT14> peak_coords, + unsigned& flag, + const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) const + { + unsigned orig_axis_count = axes_old_index_tag_map.get_population (); + auto it = peak_coords.iter (); + unsigned count = 0; + for (unsigned i = 0; i < orig_axis_count; i++) + { + if (!axes_index_map.has (i)) /* axis pinned */ + continue; + hb_tag_t axis_tag = axes_old_index_tag_map.get (i); + Triple *coords; + if (!axis_tuples.has (axis_tag, &coords)) + (*it).set_int (0); + else + (*it).set_float (coords->middle); + it++; + count++; + } + flag |= TupleVariationHeader::TuppleIndex::EmbeddedPeakTuple; + return count; + } + + /* if no need to encode intermediate coords, then just return p */ + unsigned encode_interm_coords (hb_array_t<F2DOT14> coords, + unsigned& flag, + const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) const + { + unsigned orig_axis_count = axes_old_index_tag_map.get_population (); + unsigned cur_axis_count = axes_index_map.get_population (); + + auto start_coords_iter = coords.sub_array (0, cur_axis_count).iter (); + auto end_coords_iter = coords.sub_array (cur_axis_count).iter (); + bool encode_needed = false; + unsigned count = 0; + for (unsigned i = 0; i < orig_axis_count; i++) + { + if (!axes_index_map.has (i)) /* axis pinned */ + continue; + hb_tag_t axis_tag = axes_old_index_tag_map.get (i); + Triple *coords; + float min_val = 0.f, val = 0.f, max_val = 0.f; + if (axis_tuples.has (axis_tag, &coords)) + { + min_val = coords->minimum; + val = coords->middle; + max_val = coords->maximum; + } + + (*start_coords_iter).set_float (min_val); + (*end_coords_iter).set_float (max_val); + + start_coords_iter++; + end_coords_iter++; + count += 2; + if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) + encode_needed = true; + } + + if (encode_needed) + { + flag |= TupleVariationHeader::TuppleIndex::IntermediateRegion; + return count; + } + return 0; + } + + bool compile_deltas () + { + hb_vector_t<int> rounded_deltas; + if (unlikely (!rounded_deltas.alloc (indices.length))) + return false; + + for (unsigned i = 0; i < indices.length; i++) + { + if (!indices[i]) continue; + int rounded_delta = (int) roundf (deltas_x[i]); + rounded_deltas.push (rounded_delta); + } + + if (!rounded_deltas) return false; + /* allocate enough memories 3 * num_deltas */ + unsigned alloc_len = 3 * rounded_deltas.length; + if (deltas_y) + alloc_len *= 2; + + if (unlikely (!compiled_deltas.resize (alloc_len))) return false; + + unsigned i = 0; + unsigned encoded_len = encode_delta_run (i, compiled_deltas.as_array (), rounded_deltas); + + if (deltas_y) + { + /* reuse the rounded_deltas vector, check that deltas_y have the same num of deltas as deltas_x */ + unsigned j = 0; + for (unsigned idx = 0; idx < indices.length; idx++) + { + if (!indices[idx]) continue; + int rounded_delta = (int) roundf (deltas_y[idx]); + + if (j >= rounded_deltas.length) return false; + + rounded_deltas[j++] = rounded_delta; + } + + if (j != rounded_deltas.length) return false; + encoded_len += encode_delta_run (i, compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); + } + return compiled_deltas.resize (encoded_len); + } + + unsigned encode_delta_run (unsigned& i, + hb_array_t<char> encoded_bytes, + const hb_vector_t<int>& deltas) const + { + unsigned num_deltas = deltas.length; + unsigned encoded_len = 0; + while (i < num_deltas) + { + int val = deltas[i]; + if (val == 0) + encoded_len += encode_delta_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), deltas); + else if (val >= -128 && val <= 127) + encoded_len += encode_delta_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), deltas); + else + encoded_len += encode_delta_run_as_words (i, encoded_bytes.sub_array (encoded_len), deltas); + } + return encoded_len; + } + + unsigned encode_delta_run_as_zeroes (unsigned& i, + hb_array_t<char> encoded_bytes, + const hb_vector_t<int>& deltas) const + { + unsigned num_deltas = deltas.length; + unsigned run_length = 0; + auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (i < num_deltas && deltas[i] == 0) + { + i++; + run_length++; + } + + while (run_length >= 64) + { + *it++ = (DELTAS_ARE_ZERO | 63); + run_length -= 64; + encoded_len++; + } + + if (run_length) + { + *it++ = (DELTAS_ARE_ZERO | (run_length - 1)); + encoded_len++; + } + return encoded_len; + } + + unsigned encode_delta_run_as_bytes (unsigned &i, + hb_array_t<char> encoded_bytes, + const hb_vector_t<int>& deltas) const + { + unsigned start = i; + unsigned num_deltas = deltas.length; + while (i < num_deltas) + { + int val = deltas[i]; + if (val > 127 || val < -128) + break; + + /* from fonttools: if there're 2 or more zeros in a sequence, + * it is better to start a new run to save bytes. */ + if (val == 0 && i + 1 < num_deltas && deltas[i+1] == 0) + break; + + i++; + } + unsigned run_length = i - start; + + unsigned encoded_len = 0; + auto it = encoded_bytes.iter (); + + while (run_length >= 64) + { + *it++ = 63; + encoded_len++; + + for (unsigned j = 0; j < 64; j++) + { + *it++ = static_cast<char> (deltas[start + j]); + encoded_len++; + } + + start += 64; + run_length -= 64; + } + + if (run_length) + { + *it++ = run_length - 1; + encoded_len++; + + while (start < i) + { + *it++ = static_cast<char> (deltas[start++]); + encoded_len++; + } + } + + return encoded_len; + } + + unsigned encode_delta_run_as_words (unsigned &i, + hb_array_t<char> encoded_bytes, + const hb_vector_t<int>& deltas) const + { + unsigned start = i; + unsigned num_deltas = deltas.length; + while (i < num_deltas) + { + int val = deltas[i]; + + /* start a new run for a single zero value*/ + if (val == 0) break; + + /* from fonttools: continue word-encoded run if there's only one + * single value in the range [-128, 127] because it is more compact. + * Only start a new run when there're 2 continuous such values. */ + if (val >= -128 && val <= 127 && + i + 1 < num_deltas && + deltas[i+1] >= -128 && deltas[i+1] <= 127) + break; + + i++; + } + + unsigned run_length = i - start; + auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (run_length >= 64) + { + *it++ = (DELTAS_ARE_WORDS | 63); + encoded_len++; + + for (unsigned j = 0; j < 64; j++) + { + int16_t delta_val = deltas[start + j]; + *it++ = static_cast<char> (delta_val >> 8); + *it++ = static_cast<char> (delta_val & 0xFF); + + encoded_len += 2; + } + + start += 64; + run_length -= 64; + } + + if (run_length) + { + *it++ = (DELTAS_ARE_WORDS | (run_length - 1)); + while (start < i) + { + int16_t delta_val = deltas[start++]; + *it++ = static_cast<char> (delta_val >> 8); + *it++ = static_cast<char> (delta_val & 0xFF); + + encoded_len += 2; + } + } + return encoded_len; + } +}; + struct TupleVariationData { bool sanitize (hb_sanitize_context_t *c) const @@ -378,7 +896,7 @@ struct TupleVariationData unsigned get_size (unsigned axis_count) const { unsigned total_size = min_size; - unsigned count = tupleVarCount; + unsigned count = tupleVarCount.get_count (); const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header()); for (unsigned i = 0; i < count; i++) { @@ -392,8 +910,354 @@ struct TupleVariationData const TupleVariationHeader &get_tuple_var_header (void) const { return StructAfter<TupleVariationHeader> (data); } + struct tuple_iterator_t; + struct tuple_variations_t + { + hb_vector_t<tuple_delta_t> tuple_vars; + + private: + /* referenced point set->compiled point data map */ + hb_hashmap_t<const hb_vector_t<bool>*, byte_data_t> point_data_map; + /* referenced point set-> count map, used in finding shared points */ + hb_hashmap_t<const hb_vector_t<bool>*, unsigned> point_set_count_map; + + public: + ~tuple_variations_t () { fini (); } + void fini () + { + for (auto _ : point_data_map.values ()) + _.fini (); + + point_set_count_map.fini (); + tuple_vars.fini (); + } + + unsigned get_var_count () const + { return tuple_vars.length; } + + bool create_from_tuple_var_data (tuple_iterator_t iterator, + unsigned tuple_var_count, + unsigned point_count, + bool is_gvar, + const hb_map_t *axes_old_index_tag_map, + const hb_vector_t<unsigned> &shared_indices, + const hb_array_t<const F2DOT14> shared_tuples) + { + do + { + const HBUINT8 *p = iterator.get_serialized_data (); + unsigned int length = iterator.current_tuple->get_data_size (); + if (unlikely (!iterator.var_data_bytes.check_range (p, length))) + { fini (); return false; } + + hb_hashmap_t<hb_tag_t, Triple> axis_tuples; + if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples) + || axis_tuples.is_empty ()) + { fini (); return false; } + + hb_vector_t<unsigned> private_indices; + bool has_private_points = iterator.current_tuple->has_private_points (); + const HBUINT8 *end = p + length; + if (has_private_points && + !TupleVariationData::unpack_points (p, private_indices, end)) + { fini (); return false; } + + const hb_vector_t<unsigned> &indices = has_private_points ? private_indices : shared_indices; + bool apply_to_all = (indices.length == 0); + unsigned num_deltas = apply_to_all ? point_count : indices.length; + + hb_vector_t<int> deltas_x; + + if (unlikely (!deltas_x.resize (num_deltas, false) || + !TupleVariationData::unpack_deltas (p, deltas_x, end))) + { fini (); return false; } + + hb_vector_t<int> deltas_y; + if (is_gvar) + { + if (unlikely (!deltas_y.resize (num_deltas, false) || + !TupleVariationData::unpack_deltas (p, deltas_y, end))) + { fini (); return false; } + } + + tuple_delta_t var; + var.axis_tuples = std::move (axis_tuples); + if (unlikely (!var.indices.resize (point_count) || + !var.deltas_x.resize (point_count, false))) + { fini (); return false; } + + if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) + { fini (); return false; } + + for (unsigned i = 0; i < num_deltas; i++) + { + unsigned idx = apply_to_all ? i : indices[i]; + if (idx >= point_count) continue; + var.indices[idx] = true; + var.deltas_x[idx] = static_cast<float> (deltas_x[i]); + if (is_gvar) + var.deltas_y[idx] = static_cast<float> (deltas_y[i]); + } + tuple_vars.push (std::move (var)); + } while (iterator.move_to_next ()); + return true; + } + + void change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple> *normalized_axes_location) + { + for (auto _ : *normalized_axes_location) + { + hb_tag_t axis_tag = _.first; + Triple axis_limit = _.second; + hb_vector_t<tuple_delta_t> new_vars; + for (const tuple_delta_t& var : tuple_vars) + { + hb_vector_t<tuple_delta_t> out = var.change_tuple_var_axis_limit (axis_tag, axis_limit); + if (!out) continue; + unsigned new_len = new_vars.length + out.length; + + if (unlikely (!new_vars.alloc (new_len, false))) + { fini (); return;} + + for (unsigned i = 0; i < out.length; i++) + new_vars.push (std::move (out[i])); + } + tuple_vars.fini (); + tuple_vars = std::move (new_vars); + } + } + + /* merge tuple variations with overlapping tents */ + void merge_tuple_variations () + { + hb_vector_t<tuple_delta_t> new_vars; + hb_hashmap_t<hb_hashmap_t<hb_tag_t, Triple>, unsigned> m; + unsigned i = 0; + for (const tuple_delta_t& var : tuple_vars) + { + /* if all axes are pinned, drop the tuple variation */ + if (var.axis_tuples.is_empty ()) continue; + + unsigned *idx; + if (m.has (var.axis_tuples, &idx)) + { + new_vars[*idx] += var; + } + else + { + new_vars.push (var); + m.set (var.axis_tuples, i); + i++; + } + } + tuple_vars.fini (); + tuple_vars = std::move (new_vars); + } + + byte_data_t compile_point_set (const hb_vector_t<bool> &point_indices) + { + unsigned num_points = 0; + for (bool i : point_indices) + if (i) num_points++; + + unsigned indices_length = point_indices.length; + /* If the points set consists of all points in the glyph, it's encoded with a + * single zero byte */ + if (num_points == indices_length) + { + char *p = (char *) hb_calloc (1, sizeof (char)); + if (unlikely (!p)) return byte_data_t (); + + return byte_data_t (p, 1); + } + + /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ + unsigned num_bytes = 2 + 3 *num_points; + char *p = (char *) hb_calloc (num_bytes, sizeof (char)); + if (unlikely (!p)) return byte_data_t (); + + unsigned pos = 0; + /* binary data starts with the total number of reference points */ + if (num_points < 0x80) + p[pos++] = num_points; + else + { + p[pos++] = ((num_points >> 8) | 0x80); + p[pos++] = num_points & 0xFF; + } + + const unsigned max_run_length = 0x7F; + unsigned i = 0; + unsigned last_value = 0; + unsigned num_encoded = 0; + while (i < indices_length && num_encoded < num_points) + { + unsigned run_length = 0; + unsigned header_pos = pos; + p[pos++] = 0; + + bool use_byte_encoding = false; + bool new_run = true; + while (i < indices_length && num_encoded < num_points && + run_length <= max_run_length) + { + // find out next referenced point index + while (i < indices_length && !point_indices[i]) + i++; + + if (i >= indices_length) break; + + unsigned cur_value = i; + unsigned delta = cur_value - last_value; + + if (new_run) + { + use_byte_encoding = (delta <= 0xFF); + new_run = false; + } + + if (use_byte_encoding && delta > 0xFF) + break; + + if (use_byte_encoding) + p[pos++] = delta; + else + { + p[pos++] = delta >> 8; + p[pos++] = delta & 0xFF; + } + i++; + last_value = cur_value; + run_length++; + num_encoded++; + } + + if (use_byte_encoding) + p[header_pos] = run_length - 1; + else + p[header_pos] = (run_length - 1) | 0x80; + } + return byte_data_t (p, pos); + } + + /* compile all point set and store byte data in a point_set->byte_data_t hashmap, + * also update point_set->count map, which will be used in finding shared + * point set*/ + bool compile_all_point_sets () + { + for (const auto& tuple: tuple_vars) + { + const hb_vector_t<bool>* points_set = &(tuple.indices); + if (point_data_map.has (points_set)) + { + unsigned *count; + if (unlikely (!point_set_count_map.has (points_set, &count) || + !point_set_count_map.set (points_set, (*count) + 1))) + return false; + continue; + } + + byte_data_t compiled_data = compile_point_set (*points_set); + if (unlikely (compiled_data == byte_data_t ())) + return false; + + if (!point_data_map.set (points_set, compiled_data) || + !point_set_count_map.set (points_set, 1)) + return false; + } + return true; + } + + /* find shared points set which saves most bytes */ + byte_data_t find_shared_points () + { + unsigned max_saved_bytes = 0; + byte_data_t res{}; + + for (const auto& _ : point_data_map.iter ()) + { + const hb_vector_t<bool>* points_set = _.first; + unsigned data_length = _.second.bytes.length; + unsigned *count; + if (unlikely (!point_set_count_map.has (points_set, &count) || + *count <= 1)) + return byte_data_t (); + + unsigned saved_bytes = data_length * ((*count) -1); + if (saved_bytes > max_saved_bytes) + { + max_saved_bytes = saved_bytes; + res = _.second; + } + } + return res; + } + + void instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location) + { + change_tuple_variations_axis_limits (&normalized_axes_location); + merge_tuple_variations (); + } + + bool compile_bytes (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) + { + // compile points set and store data in hashmap + if (!compile_all_point_sets ()) + return false; + // compile delta and tuple var header for each tuple variation + for (auto& tuple: tuple_vars) + { + const hb_vector_t<bool>* points_set = &(tuple.indices); + byte_data_t *points_data; + if (unlikely (!point_data_map.has (points_set, &points_data))) + return false; + + if (!tuple.compile_deltas ()) + return false; + + if (!tuple.compile_tuple_var_header (axes_index_map, points_data->bytes.length, axes_old_index_tag_map)) + return false; + } + return true; + } + + bool serialize_var_headers (hb_serialize_context_t *c, unsigned& total_header_len) const + { + TRACE_SERIALIZE (this); + for (const auto& tuple: tuple_vars) + { + byte_data_t compiled_bytes {tuple.compiled_tuple_header.arrayZ, tuple.compiled_tuple_header.length}; + compiled_bytes.copy (c); + if (c->in_error ()) return_trace (false); + total_header_len += tuple.compiled_tuple_header.length; + } + return_trace (true); + } + + bool serialize_var_data (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + for (const auto& tuple: tuple_vars) + { + const hb_vector_t<bool>* points_set = &(tuple.indices); + byte_data_t *point_data; + if (!point_data_map.has (points_set, &point_data)) + return_trace (false); + + point_data->copy (c); + byte_data_t compiled_bytes {tuple.compiled_deltas.arrayZ, tuple.compiled_deltas.length}; + compiled_bytes.copy (c); + if (c->in_error ()) return_trace (false); + } + return_trace (true); + } + }; + struct tuple_iterator_t { + unsigned get_axis_count () const { return axis_count; } + void init (hb_bytes_t var_data_bytes_, unsigned int axis_count_, const void *table_base_) { var_data_bytes = var_data_bytes_; @@ -517,13 +1381,6 @@ struct TupleVariationData hb_vector_t<int> &deltas /* IN/OUT */, const HBUINT8 *end) { - enum packed_delta_flag_t - { - DELTAS_ARE_ZERO = 0x80, - DELTAS_ARE_WORDS = 0x40, - DELTA_RUN_COUNT_MASK = 0x3F - }; - unsigned i = 0; unsigned count = deltas.length; while (i < count) @@ -561,11 +1418,50 @@ struct TupleVariationData bool has_data () const { return tupleVarCount; } + bool decompile_tuple_variations (unsigned point_count, + bool is_gvar, + tuple_iterator_t iterator, + const hb_map_t *axes_old_index_tag_map, + const hb_vector_t<unsigned> &shared_indices, + const hb_array_t<const F2DOT14> shared_tuples, + tuple_variations_t& tuple_variations /* OUT */) const + { + return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, + point_count, is_gvar, + axes_old_index_tag_map, + shared_indices, + shared_tuples); + } + + bool serialize (hb_serialize_context_t *c, + bool is_gvar, + tuple_variations_t& tuple_variations) const + { + TRACE_SERIALIZE (this); + auto *out = c->start_embed (this); + if (unlikely (!c->extend_min (out))) return_trace (false); + + if (!c->check_assign (out->tupleVarCount, tuple_variations.get_var_count (), + HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); + + unsigned total_header_len = 0; + + if (!tuple_variations.serialize_var_headers (c, total_header_len)) + return_trace (false); + + unsigned data_offset = min_size + total_header_len; + if (!is_gvar) data_offset += 4; + if (!c->check_assign (out->data, data_offset, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); + + return tuple_variations.serialize_var_data (c); + } + protected: struct TupleVarCount : HBUINT16 { bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); } unsigned int get_count () const { return (*this) & CountMask; } + TupleVarCount& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } protected: enum Flags diff --git a/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh index 7fd0f1d79d..de54339301 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh @@ -27,6 +27,7 @@ #define HB_OT_VAR_CVAR_TABLE_HH #include "hb-ot-var-common.hh" +#include "hb-ot-var-fvar-table.hh" namespace OT { @@ -51,6 +52,27 @@ struct cvar const TupleVariationData* get_tuple_var_data (void) const { return &tupleVariationData; } + bool decompile_tuple_variations (unsigned axis_count, + unsigned point_count, + bool is_gvar, + const hb_map_t *axes_old_index_tag_map, + TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const + { + hb_vector_t<unsigned> shared_indices; + TupleVariationData::tuple_iterator_t iterator; + unsigned var_data_length = tupleVariationData.get_size (axis_count); + hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast<const char*> (get_tuple_var_data ()), var_data_length); + if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this, + shared_indices, &iterator)) + return false; + + return tupleVariationData.decompile_tuple_variations (point_count, is_gvar, iterator, + axes_old_index_tag_map, + shared_indices, + hb_array<const F2DOT14> (), + tuple_variations); + } + static bool calculate_cvt_deltas (unsigned axis_count, hb_array_t<int> coords, unsigned num_cvt_item, @@ -104,6 +126,53 @@ struct cvar return true; } + + bool serialize (hb_serialize_context_t *c, + TupleVariationData::tuple_variations_t& tuple_variations) const + { + TRACE_SERIALIZE (this); + if (unlikely (!c->embed (version))) return_trace (false); + + return_trace (tupleVariationData.serialize (c, false, tuple_variations)); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + if (c->plan->all_axes_pinned) + return_trace (false); + + /* subset() for cvar is called by partial instancing only, we always pass + * through cvar table in other cases */ + if (!c->plan->normalized_coords) + { + unsigned axis_count = c->plan->source->table.fvar->get_axis_count (); + unsigned total_size = min_size + tupleVariationData.get_size (axis_count); + char *out = c->serializer->allocate_size<char> (total_size); + if (unlikely (!out)) return_trace (false); + + hb_memcpy (out, this, total_size); + return_trace (true); + } + + OT::TupleVariationData::tuple_variations_t tuple_variations; + unsigned axis_count = c->plan->axes_old_index_tag_map.get_population (); + + const hb_tag_t cvt = HB_TAG('c','v','t',' '); + hb_blob_t *cvt_blob = hb_face_reference_table (c->plan->source, cvt); + unsigned point_count = hb_blob_get_length (cvt_blob) / FWORD::static_size; + + if (!decompile_tuple_variations (axis_count, point_count, false, + &(c->plan->axes_old_index_tag_map), + tuple_variations)) + return_trace (false); + + tuple_variations.instantiate (c->plan->axes_location); + if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map)) + return_trace (false); + + return_trace (serialize (c->serializer, tuple_variations)); + } static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan, const TupleVariationData *tuple_var_data, diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh index a384dfa531..d8e789cb44 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh @@ -39,6 +39,24 @@ namespace OT { +static bool axis_coord_pinned_or_within_axis_range (const hb_array_t<const F16DOT16> coords, + unsigned axis_index, + Triple axis_limit) +{ + float axis_coord = coords[axis_index].to_float (); + if (axis_limit.is_point ()) + { + if (axis_limit.minimum != axis_coord) + return false; + } + else + { + if (axis_coord < axis_limit.minimum || + axis_coord > axis_limit.maximum) + return false; + } + return true; +} struct InstanceRecord { @@ -47,6 +65,27 @@ struct InstanceRecord hb_array_t<const F16DOT16> get_coordinates (unsigned int axis_count) const { return coordinatesZ.as_array (axis_count); } + bool keep_instance (unsigned axis_count, + const hb_map_t *axes_index_tag_map, + const hb_hashmap_t<hb_tag_t, Triple> *axes_location) const + { + if (axes_location->is_empty ()) return true; + const hb_array_t<const F16DOT16> coords = get_coordinates (axis_count); + for (unsigned i = 0 ; i < axis_count; i++) + { + uint32_t *axis_tag; + if (!axes_index_tag_map->has (i, &axis_tag)) + return false; + if (!axes_location->has (*axis_tag)) + continue; + + Triple axis_limit = axes_location->get (*axis_tag); + if (!axis_coord_pinned_or_within_axis_range (coords, i, axis_limit)) + return false; + } + return true; + } + bool subset (hb_subset_context_t *c, unsigned axis_count, bool has_postscript_nameid) const @@ -56,19 +95,22 @@ struct InstanceRecord if (unlikely (!c->serializer->embed (flags))) return_trace (false); const hb_array_t<const F16DOT16> coords = get_coordinates (axis_count); - const hb_hashmap_t<hb_tag_t, float> *axes_location = &c->plan->user_axes_location; + const hb_hashmap_t<hb_tag_t, Triple> *axes_location = &c->plan->user_axes_location; for (unsigned i = 0 ; i < axis_count; i++) { uint32_t *axis_tag; // only keep instances whose coordinates == pinned axis location if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) continue; - - if (axes_location->has (*axis_tag) && - fabsf (axes_location->get (*axis_tag) - coords[i].to_float ()) > 0.001f) - return_trace (false); - - if (!c->plan->axes_index_map.has (i)) - continue; + if (axes_location->has (*axis_tag)) + { + Triple axis_limit = axes_location->get (*axis_tag); + if (!axis_coord_pinned_or_within_axis_range (coords, i, axis_limit)) + return_trace (false); + + //skip pinned axis + if (axis_limit.is_point ()) + continue; + } if (!c->serializer->embed (coords[i])) return_trace (false); @@ -216,7 +258,8 @@ struct fvar axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && get_axes ().sanitize (c) && - c->check_range (get_instance (0), instanceCount, instanceSize)); + c->check_range (&StructAfter<InstanceRecord> (get_axes ()), + instanceCount, instanceSize)); } unsigned int get_axis_count () const { return axisCount; } @@ -314,21 +357,19 @@ struct fvar return axisCount; } - void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location, + void collect_name_ids (hb_hashmap_t<hb_tag_t, Triple> *user_axes_location, + hb_map_t *axes_old_index_tag_map, hb_set_t *nameids /* IN/OUT */) const { if (!has_data ()) return; - hb_map_t pinned_axes; auto axis_records = get_axes (); for (unsigned i = 0 ; i < (unsigned)axisCount; i++) { hb_tag_t axis_tag = axis_records[i].get_axis_tag (); - if (user_axes_location->has (axis_tag)) - { - pinned_axes.set (i, axis_tag); + if (user_axes_location->has (axis_tag) && + user_axes_location->get (axis_tag).is_point ()) continue; - } nameids->add (axis_records[i].get_name_id ()); } @@ -337,16 +378,7 @@ struct fvar { const InstanceRecord *instance = get_instance (i); - if (hb_any (+ hb_enumerate (instance->get_coordinates (axisCount)) - | hb_filter (pinned_axes, hb_first) - | hb_map ([&] (const hb_pair_t<unsigned, const F16DOT16&>& _) - { - hb_tag_t axis_tag = pinned_axes.get (_.first); - float location = user_axes_location->get (axis_tag); - if (fabs ((double)location - (double)_.second.to_float ()) > 0.001) return true; - return false; - }) - )) + if (!instance->keep_instance (axisCount, axes_old_index_tag_map, user_axes_location)) continue; nameids->add (instance->subfamilyNameID); diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh index ece892e1dd..b5099ac074 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh @@ -50,13 +50,14 @@ struct contour_point_t y = x * matrix[1] + y * matrix[3]; x = x_; } + HB_ALWAYS_INLINE void translate (const contour_point_t &p) { x += p.x; y += p.y; } - float x = 0.f; - float y = 0.f; - uint8_t flag = 0; - bool is_end_point = false; + float x; + float y; + uint8_t flag; + bool is_end_point; }; struct contour_point_vector_t : hb_vector_t<contour_point_t> @@ -110,20 +111,20 @@ struct gvar unsigned int num_glyphs = c->plan->num_output_glyphs (); out->glyphCountX = hb_min (0xFFFFu, num_glyphs); + auto it = hb_iter (c->plan->new_to_old_gid_list); + if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + it++; unsigned int subset_data_size = 0; - for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1; - gid < num_glyphs; - gid++) + for (auto &_ : it) { - hb_codepoint_t old_gid; - if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue; + hb_codepoint_t old_gid = _.second; subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; } bool long_offset = subset_data_size & ~0xFFFFu; out->flags = long_offset ? 1 : 0; - HBUINT8 *subset_offsets = c->serializer->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1)); + HBUINT8 *subset_offsets = c->serializer->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1), false); if (!subset_offsets) return_trace (false); /* shared tuples */ @@ -138,36 +139,61 @@ struct gvar hb_memcpy (tuples, this+sharedTuples, shared_tuple_size); } - char *subset_data = c->serializer->allocate_size<char> (subset_data_size); + char *subset_data = c->serializer->allocate_size<char> (subset_data_size, false); if (!subset_data) return_trace (false); out->dataZ = subset_data - (char *) out; + + if (long_offset) + { + ((HBUINT32 *) subset_offsets)[0] = 0; + subset_offsets += 4; + } + else + { + ((HBUINT16 *) subset_offsets)[0] = 0; + subset_offsets += 2; + } unsigned int glyph_offset = 0; - for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1; - gid < num_glyphs; - gid++) + + hb_codepoint_t last = 0; + it = hb_iter (c->plan->new_to_old_gid_list); + if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + it++; + for (auto &_ : it) { - hb_codepoint_t old_gid; - hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid) - ? get_glyph_var_data_bytes (c->source_blob, + hb_codepoint_t gid = _.first; + hb_codepoint_t old_gid = _.second; + + if (long_offset) + for (; last < gid; last++) + ((HBUINT32 *) subset_offsets)[last] = glyph_offset; + else + for (; last < gid; last++) + ((HBUINT16 *) subset_offsets)[last] = glyph_offset / 2; + + hb_bytes_t var_data_bytes = get_glyph_var_data_bytes (c->source_blob, glyph_count, - old_gid) - : hb_bytes_t (); + old_gid); + + hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length); + subset_data += var_data_bytes.length; + glyph_offset += var_data_bytes.length; if (long_offset) ((HBUINT32 *) subset_offsets)[gid] = glyph_offset; else ((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2; - if (var_data_bytes.length > 0) - hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length); - subset_data += var_data_bytes.length; - glyph_offset += var_data_bytes.length; + last++; // Skip over gid } + if (long_offset) - ((HBUINT32 *) subset_offsets)[num_glyphs] = glyph_offset; + for (; last < num_glyphs; last++) + ((HBUINT32 *) subset_offsets)[last] = glyph_offset; else - ((HBUINT16 *) subset_offsets)[num_glyphs] = glyph_offset / 2; + for (; last < num_glyphs; last++) + ((HBUINT16 *) subset_offsets)[last] = glyph_offset / 2; return_trace (true); } @@ -216,21 +242,24 @@ struct gvar for (unsigned i = 0; i < count; i++) { hb_array_t<const F2DOT14> tuple = shared_tuples.sub_array (axis_count * i, axis_count); - int idx = -1; + int idx1 = -1, idx2 = -1; for (unsigned j = 0; j < axis_count; j++) { const F2DOT14 &peak = tuple.arrayZ[j]; if (peak.to_int () != 0) { - if (idx != -1) + if (idx1 == -1) + idx1 = j; + else if (idx2 == -1) + idx2 = j; + else { - idx = -1; + idx1 = idx2 = -1; break; } - idx = j; } } - shared_tuple_active_idx.arrayZ[i] = idx; + shared_tuple_active_idx.arrayZ[i] = {idx1, idx2}; } } ~accelerator_t () { table.destroy (); } @@ -266,10 +295,9 @@ struct gvar public: bool apply_deltas_to_points (hb_codepoint_t glyph, hb_array_t<int> coords, - const hb_array_t<contour_point_t> points) const + const hb_array_t<contour_point_t> points, + bool phantom_only = false) const { - if (!coords) return true; - if (unlikely (glyph >= glyphCount)) return true; hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph); @@ -297,6 +325,7 @@ struct gvar hb_vector_t<unsigned int> private_indices; hb_vector_t<int> x_deltas; hb_vector_t<int> y_deltas; + unsigned count = points.length; bool flush = false; do { @@ -310,9 +339,10 @@ struct gvar if (!deltas) { - if (unlikely (!deltas_vec.resize (points.length, false))) return false; + if (unlikely (!deltas_vec.resize (count, false))) return false; deltas = deltas_vec.as_array (); - hb_memset (deltas.arrayZ, 0, deltas.get_size ()); // Faster than vector resize + hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0, + (phantom_only ? 4 : count) * sizeof (deltas[0])); } const HBUINT8 *end = p + length; @@ -332,7 +362,7 @@ struct gvar if (!apply_to_all) { - if (!orig_points) + if (!orig_points && !phantom_only) { orig_points_vec.extend (points); if (unlikely (orig_points_vec.in_error ())) return false; @@ -341,13 +371,13 @@ struct gvar if (flush) { - unsigned count = points.length; - for (unsigned int i = 0; i < count; i++) + for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) points.arrayZ[i].translate (deltas.arrayZ[i]); flush = false; } - hb_memset (deltas.arrayZ, 0, deltas.get_size ()); + hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0, + (phantom_only ? 4 : count) * sizeof (deltas[0])); } if (HB_OPTIMIZE_SIZE_VAL) @@ -362,6 +392,7 @@ struct gvar pt_index = indices[i]; if (unlikely (pt_index >= deltas.length)) continue; } + if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ delta.x += x_deltas.arrayZ[i] * scalar; @@ -374,7 +405,7 @@ struct gvar if (scalar != 1.0f) { if (apply_to_all) - for (unsigned int i = 0; i < num_deltas; i++) + for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { unsigned int pt_index = i; auto &delta = deltas.arrayZ[pt_index]; @@ -386,6 +417,7 @@ struct gvar { unsigned int pt_index = indices[i]; if (unlikely (pt_index >= deltas.length)) continue; + if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ delta.x += x_deltas.arrayZ[i] * scalar; @@ -395,7 +427,7 @@ struct gvar else { if (apply_to_all) - for (unsigned int i = 0; i < num_deltas; i++) + for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { unsigned int pt_index = i; auto &delta = deltas.arrayZ[pt_index]; @@ -407,6 +439,7 @@ struct gvar { unsigned int pt_index = indices[i]; if (unlikely (pt_index >= deltas.length)) continue; + if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ delta.x += x_deltas.arrayZ[i]; @@ -416,11 +449,10 @@ struct gvar } /* infer deltas for unreferenced points */ - if (!apply_to_all) + if (!apply_to_all && !phantom_only) { if (!end_points) { - unsigned count = points.length; for (unsigned i = 0; i < count; ++i) if (points.arrayZ[i].is_end_point) end_points.push (i); @@ -482,8 +514,7 @@ struct gvar if (flush) { - unsigned count = points.length; - for (unsigned int i = 0; i < count; i++) + for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) points.arrayZ[i].translate (deltas.arrayZ[i]); } @@ -495,7 +526,7 @@ struct gvar private: hb_blob_ptr_t<gvar> table; unsigned glyphCount; - hb_vector_t<signed> shared_tuple_active_idx; + hb_vector_t<hb_pair_t<int, int>> shared_tuple_active_idx; }; protected: diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh index 461b2b9cdb..943d376bdf 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh @@ -56,52 +56,56 @@ struct index_map_subset_plan_t if (&index_map == &Null (DeltaSetIndexMap)) return; unsigned int last_val = (unsigned int)-1; - hb_codepoint_t last_gid = (hb_codepoint_t)-1; - hb_codepoint_t gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ()); + hb_codepoint_t last_gid = HB_CODEPOINT_INVALID; + hb_codepoint_t num_gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ()); outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count (); max_inners.resize (inner_sets.length); for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0; /* Search backwards for a map value different from the last map value */ - for (; gid > 0; gid--) + auto &new_to_old_gid_list = plan->new_to_old_gid_list; + unsigned count = new_to_old_gid_list.length; + for (unsigned j = count; j; j--) { - hb_codepoint_t old_gid; - if (!plan->old_gid_for_new_gid (gid - 1, &old_gid)) - { - if (last_gid == (hb_codepoint_t) -1) - continue; - else - break; - } + hb_codepoint_t gid = new_to_old_gid_list[j - 1].first; + if (gid >= num_gid) continue; + + hb_codepoint_t old_gid = new_to_old_gid_list[j - 1].second; unsigned int v = index_map.map (old_gid); - if (last_gid == (hb_codepoint_t) -1) + if (last_gid == HB_CODEPOINT_INVALID) { + if (gid + 1 != num_gid) + { + last_gid = gid + 1; + break; + } last_val = v; last_gid = gid; continue; } - if (v != last_val) break; + if (v != last_val || gid + 1 != last_gid) + break; last_gid = gid; } if (unlikely (last_gid == (hb_codepoint_t)-1)) return; - map_count = last_gid; - for (gid = 0; gid < map_count; gid++) + map_count = last_gid + 1; + for (auto _ : plan->new_to_old_gid_list) { - hb_codepoint_t old_gid; - if (plan->old_gid_for_new_gid (gid, &old_gid)) - { - unsigned int v = index_map.map (old_gid); - unsigned int outer = v >> 16; - unsigned int inner = v & 0xFFFF; - outer_map.add (outer); - if (inner > max_inners[outer]) max_inners[outer] = inner; - if (outer >= inner_sets.length) return; - inner_sets[outer]->add (inner); - } + hb_codepoint_t gid = _.first; + if (gid >= map_count) break; + + hb_codepoint_t old_gid = _.second; + unsigned int v = index_map.map (old_gid); + unsigned int outer = v >> 16; + unsigned int inner = v & 0xFFFF; + outer_map.add (outer); + if (inner > max_inners[outer]) max_inners[outer] = inner; + if (outer >= inner_sets.length) return; + inner_sets[outer]->add (inner); } } @@ -197,7 +201,8 @@ struct hvarvvar_subset_plan_t if (retain_adv_map) { - for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) + unsigned num_glyphs = plan->num_output_glyphs (); + for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) { if (inner_sets[0]->has (gid)) inner_maps[0].add (gid); diff --git a/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh b/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh index 811e13919e..671b6d2c29 100644 --- a/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh @@ -90,7 +90,7 @@ struct VORG bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - VORG *vorg_prime = c->serializer->start_embed<VORG> (); + auto *vorg_prime = c->serializer->start_embed<VORG> (); if (unlikely (!c->serializer->check_success (vorg_prime))) return_trace (false); auto it = diff --git a/thirdparty/harfbuzz/src/hb-pool.hh b/thirdparty/harfbuzz/src/hb-pool.hh index d6eb778f5d..fcf10666b0 100644 --- a/thirdparty/harfbuzz/src/hb-pool.hh +++ b/thirdparty/harfbuzz/src/hb-pool.hh @@ -58,7 +58,7 @@ struct hb_pool_t if (unlikely (!next)) { if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr; - chunk_t *chunk = (chunk_t *) hb_calloc (1, sizeof (chunk_t)); + chunk_t *chunk = (chunk_t *) hb_malloc (sizeof (chunk_t)); if (unlikely (!chunk)) return nullptr; chunks.push (chunk); next = chunk->thread (); diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh index 5259891b7e..2d338c51c8 100644 --- a/thirdparty/harfbuzz/src/hb-sanitize.hh +++ b/thirdparty/harfbuzz/src/hb-sanitize.hh @@ -122,12 +122,14 @@ struct hb_sanitize_context_t : { hb_sanitize_context_t () : start (nullptr), end (nullptr), + length (0), max_ops (0), max_subtables (0), recursion_depth (0), writable (false), edit_count (0), blob (nullptr), num_glyphs (65536), - num_glyphs_set (false) {} + num_glyphs_set (false), + lazy_some_gpos (false) {} const char *get_name () { return "SANITIZE"; } template <typename T, typename F> @@ -155,6 +157,19 @@ struct hb_sanitize_context_t : dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) ) + hb_sanitize_context_t (hb_blob_t *b) : hb_sanitize_context_t () + { + init (b); + + if (blob) + start_processing (); + } + + ~hb_sanitize_context_t () + { + if (blob) + end_processing (); + } void init (hb_blob_t *b) { @@ -180,11 +195,15 @@ struct hb_sanitize_context_t : const char *obj_start = (const char *) obj; if (unlikely (obj_start < this->start || this->end <= obj_start)) + { this->start = this->end = nullptr; + this->length = 0; + } else { this->start = obj_start; this->end = obj_start + hb_min (size_t (this->end - obj_start), obj->get_size ()); + this->length = this->end - this->start; } } @@ -192,6 +211,7 @@ struct hb_sanitize_context_t : { this->start = this->blob->data; this->end = this->start + this->blob->length; + this->length = this->end - this->start; assert (this->start <= this->end); /* Must not overflow. */ } @@ -224,6 +244,7 @@ struct hb_sanitize_context_t : hb_blob_destroy (this->blob); this->blob = nullptr; this->start = this->end = nullptr; + this->length = 0; } unsigned get_edit_count () { return edit_count; } @@ -240,15 +261,16 @@ struct hb_sanitize_context_t : return (this->max_ops -= (int) count) > 0; } +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif bool check_range (const void *base, unsigned int len) const { const char *p = (const char *) base; - bool ok = !len || - (this->start <= p && - p <= this->end && - (unsigned int) (this->end - p) >= len && - (this->max_ops -= len) > 0); + bool ok = (uintptr_t) (p - this->start) <= this->length && + (unsigned int) (this->end - p) >= len && + ((this->max_ops -= len) > 0); DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, "check_range [%p..%p]" @@ -259,6 +281,43 @@ struct hb_sanitize_context_t : return likely (ok); } +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + bool check_range_fast (const void *base, + unsigned int len) const + { + const char *p = (const char *) base; + bool ok = ((uintptr_t) (p - this->start) <= this->length && + (unsigned int) (this->end - p) >= len); + + DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, + "check_range_fast [%p..%p]" + " (%u bytes) in [%p..%p] -> %s", + p, p + len, len, + this->start, this->end, + ok ? "OK" : "OUT-OF-RANGE"); + + return likely (ok); + } + +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + bool check_point (const void *base) const + { + const char *p = (const char *) base; + bool ok = (uintptr_t) (p - this->start) <= this->length; + + DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, + "check_point [%p]" + " in [%p..%p] -> %s", + p, + this->start, this->end, + ok ? "OK" : "OUT-OF-RANGE"); + + return likely (ok); + } template <typename T> bool check_range (const T *base, @@ -282,6 +341,20 @@ struct hb_sanitize_context_t : } template <typename T> + HB_ALWAYS_INLINE + bool check_array_sized (const T *base, unsigned int len, unsigned len_size) const + { + if (len_size >= 4) + { + if (unlikely (hb_unsigned_mul_overflows (len, hb_static_size (T), &len))) + return false; + } + else + len = len * hb_static_size (T); + return this->check_range (base, len); + } + + template <typename T> bool check_array (const T *base, unsigned int len) const { return this->check_range (base, len, hb_static_size (T)); @@ -292,7 +365,7 @@ struct hb_sanitize_context_t : unsigned int a, unsigned int b) const { - return this->check_range (base, a, b, hb_static_size (T)); + return this->check_range (base, hb_static_size (T), a, b); } bool check_start_recursion (int max_depth) @@ -309,7 +382,12 @@ struct hb_sanitize_context_t : template <typename Type> bool check_struct (const Type *obj) const - { return likely (this->check_range (obj, obj->min_size)); } + { + if (sizeof (uintptr_t) == sizeof (uint32_t)) + return likely (this->check_range_fast (obj, obj->min_size)); + else + return likely (this->check_point ((const char *) obj + obj->min_size)); + } bool may_edit (const void *base, unsigned int len) { @@ -416,6 +494,7 @@ struct hb_sanitize_context_t : } const char *start, *end; + unsigned length; mutable int max_ops, max_subtables; private: int recursion_depth; @@ -424,6 +503,8 @@ struct hb_sanitize_context_t : hb_blob_t *blob; unsigned int num_glyphs; bool num_glyphs_set; + public: + bool lazy_some_gpos; }; struct hb_sanitize_with_object_t diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh index 61ec0253a0..f852f07ba6 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -113,7 +113,7 @@ struct hb_serialize_context_t { // Virtual links aren't considered for equality since they don't affect the functionality // of the object. - return hb_bytes_t (head, tail - head).hash () ^ + return hb_bytes_t (head, hb_min (128, tail - head)).hash () ^ real_links.as_bytes ().hash (); } @@ -172,8 +172,14 @@ struct hb_serialize_context_t }; snapshot_t snapshot () - { return snapshot_t { - head, tail, current, current->real_links.length, current->virtual_links.length, errors }; } + { + return snapshot_t { + head, tail, current, + current ? current->real_links.length : 0, + current ? current->virtual_links.length : 0, + errors + }; + } hb_serialize_context_t (void *start_, unsigned int size) : start ((char *) start_), @@ -261,6 +267,7 @@ struct hb_serialize_context_t /* To be called around main operation. */ template <typename Type> + __attribute__((returns_nonnull)) Type *start_serialize () { DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1, @@ -303,6 +310,7 @@ struct hb_serialize_context_t } template <typename Type = void> + __attribute__((returns_nonnull)) Type *push () { if (unlikely (in_error ())) return start_embed<Type> (); @@ -323,6 +331,8 @@ struct hb_serialize_context_t { object_t *obj = current; if (unlikely (!obj)) return; + // Allow cleanup when we've error'd out on int overflows which don't compromise + // the serializer state. if (unlikely (in_error() && !only_overflow ())) return; current = current->next; @@ -340,7 +350,9 @@ struct hb_serialize_context_t { object_t *obj = current; if (unlikely (!obj)) return 0; - if (unlikely (in_error())) return 0; + // Allow cleanup when we've error'd out on int overflows which don't compromise + // the serializer state. + if (unlikely (in_error() && !only_overflow ())) return 0; current = current->next; obj->tail = head; @@ -405,8 +417,11 @@ struct hb_serialize_context_t // Overflows that happened after the snapshot will be erased by the revert. if (unlikely (in_error () && !only_overflow ())) return; assert (snap.current == current); - current->real_links.shrink (snap.num_real_links); - current->virtual_links.shrink (snap.num_virtual_links); + if (current) + { + current->real_links.shrink (snap.num_real_links); + current->virtual_links.shrink (snap.num_virtual_links); + } errors = snap.errors; revert (snap.head, snap.tail); } @@ -563,13 +578,15 @@ struct hb_serialize_context_t { unsigned int l = length () % alignment; if (l) - allocate_size<void> (alignment - l); + (void) allocate_size<void> (alignment - l); } template <typename Type = void> + __attribute__((returns_nonnull)) Type *start_embed (const Type *obj HB_UNUSED = nullptr) const { return reinterpret_cast<Type *> (this->head); } template <typename Type> + __attribute__((returns_nonnull)) Type *start_embed (const Type &obj) const { return start_embed (std::addressof (obj)); } @@ -597,6 +614,7 @@ struct hb_serialize_context_t } template <typename Type> + HB_NODISCARD Type *allocate_size (size_t size, bool clear = true) { if (unlikely (in_error ())) return nullptr; @@ -618,6 +636,7 @@ struct hb_serialize_context_t { return this->allocate_size<Type> (Type::min_size); } template <typename Type> + HB_NODISCARD Type *embed (const Type *obj) { unsigned int size = obj->get_size (); @@ -627,6 +646,7 @@ struct hb_serialize_context_t return ret; } template <typename Type> + HB_NODISCARD Type *embed (const Type &obj) { return embed (std::addressof (obj)); } char *embed (const char *obj, unsigned size) diff --git a/thirdparty/harfbuzz/src/hb-set-digest.hh b/thirdparty/harfbuzz/src/hb-set-digest.hh index dab713729b..5681641baa 100644 --- a/thirdparty/harfbuzz/src/hb-set-digest.hh +++ b/thirdparty/harfbuzz/src/hb-set-digest.hh @@ -88,14 +88,19 @@ struct hb_set_digest_bits_pattern_t bool add_range (hb_codepoint_t a, hb_codepoint_t b) { + if (mask == (mask_t) -1) return false; if ((b >> shift) - (a >> shift) >= mask_bits - 1) + { mask = (mask_t) -1; - else { + return false; + } + else + { mask_t ma = mask_for (a); mask_t mb = mask_for (b); mask |= mb + (mb - ma) - (mb < ma); + return true; } - return true; } template <typename T> @@ -154,8 +159,7 @@ struct hb_set_digest_combiner_t bool add_range (hb_codepoint_t a, hb_codepoint_t b) { - return head.add_range (a, b) && - tail.add_range (a, b); + return (int) head.add_range (a, b) | (int) tail.add_range (a, b); } template <typename T> void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) diff --git a/thirdparty/harfbuzz/src/hb-set.h b/thirdparty/harfbuzz/src/hb-set.h index de53231030..192abf6f63 100644 --- a/thirdparty/harfbuzz/src/hb-set.h +++ b/thirdparty/harfbuzz/src/hb-set.h @@ -43,7 +43,7 @@ HB_BEGIN_DECLS * * Since: 0.9.21 */ -#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1) +#define HB_SET_VALUE_INVALID HB_CODEPOINT_INVALID /** * hb_set_t: diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh index 604802381b..7d1c941e4d 100644 --- a/thirdparty/harfbuzz/src/hb-set.hh +++ b/thirdparty/harfbuzz/src/hb-set.hh @@ -115,7 +115,7 @@ struct hb_sparseset_t /* Sink interface. */ hb_sparseset_t& operator << (hb_codepoint_t v) { add (v); return *this; } - hb_sparseset_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) + hb_sparseset_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } bool intersects (hb_codepoint_t first, hb_codepoint_t last) const @@ -174,7 +174,7 @@ struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t> hb_set_t& operator << (hb_codepoint_t v) { sparseset::operator<< (v); return *this; } - hb_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) + hb_set_t& operator << (const hb_codepoint_pair_t& range) { sparseset::operator<< (range); return *this; } }; diff --git a/thirdparty/harfbuzz/src/hb-shape.cc b/thirdparty/harfbuzz/src/hb-shape.cc index d9598fc704..844f7b9e80 100644 --- a/thirdparty/harfbuzz/src/hb-shape.cc +++ b/thirdparty/harfbuzz/src/hb-shape.cc @@ -220,7 +220,7 @@ reset_buffer (hb_buffer_t *buffer, assert (buffer->ensure (text.length)); buffer->have_positions = false; buffer->len = text.length; - memcpy (buffer->info, text.arrayZ, text.length * sizeof (buffer->info[0])); + hb_memcpy (buffer->info, text.arrayZ, text.length * sizeof (buffer->info[0])); hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE); } diff --git a/thirdparty/harfbuzz/src/hb-shaper-list.hh b/thirdparty/harfbuzz/src/hb-shaper-list.hh index 4158b7094c..f079caf4d3 100644 --- a/thirdparty/harfbuzz/src/hb-shaper-list.hh +++ b/thirdparty/harfbuzz/src/hb-shaper-list.hh @@ -33,6 +33,11 @@ /* v--- Add new shapers in the right place here. */ +#ifdef HAVE_WASM +/* Only picks up fonts that have a "Wasm" table. */ +HB_SHAPER_IMPLEMENT (wasm) +#endif + #ifdef HAVE_GRAPHITE2 /* Only picks up fonts that have a "Silf" table. */ HB_SHAPER_IMPLEMENT (graphite2) diff --git a/thirdparty/harfbuzz/src/hb-static.cc b/thirdparty/harfbuzz/src/hb-static.cc index a1a2522edf..c9bd0a61bf 100644 --- a/thirdparty/harfbuzz/src/hb-static.cc +++ b/thirdparty/harfbuzz/src/hb-static.cc @@ -31,6 +31,7 @@ #include "hb-aat-layout-common.hh" #include "hb-aat-layout-feat-table.hh" +#include "hb-cff-interp-common.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-cmap-table.hh" #include "OT/Color/COLR/COLR.hh" @@ -58,6 +59,8 @@ DEFINE_NULL_NAMESPACE_BYTES (AAT, Lookup) = {0xFF,0xFF}; /* hb_map_t */ const hb_codepoint_t minus_1 = -1; +static const unsigned char static_endchar_str[] = {OpCode_endchar}; +const unsigned char *endchar_str = static_endchar_str; /* hb_face_t */ diff --git a/thirdparty/harfbuzz/src/hb-subset-accelerator.hh b/thirdparty/harfbuzz/src/hb-subset-accelerator.hh index bb7c62d064..9258383d28 100644 --- a/thirdparty/harfbuzz/src/hb-subset-accelerator.hh +++ b/thirdparty/harfbuzz/src/hb-subset-accelerator.hh @@ -42,7 +42,9 @@ struct cff_subset_accelerator_t; namespace OT { struct SubtableUnicodesCache; -}; +struct cff1_subset_accelerator_t; +struct cff2_subset_accelerator_t; +} struct hb_subset_accelerator_t { @@ -51,8 +53,8 @@ struct hb_subset_accelerator_t return &_hb_subset_accelerator_user_data_key; } - static hb_subset_accelerator_t* create(const hb_map_t& unicode_to_gid_, - const hb_multimap_t gid_to_unicodes_, + static hb_subset_accelerator_t* create(hb_face_t *source, + const hb_map_t& unicode_to_gid_, const hb_set_t& unicodes_, bool has_seac_) { hb_subset_accelerator_t* accel = @@ -60,8 +62,8 @@ struct hb_subset_accelerator_t if (unlikely (!accel)) return accel; - new (accel) hb_subset_accelerator_t (unicode_to_gid_, - gid_to_unicodes_, + new (accel) hb_subset_accelerator_t (source, + unicode_to_gid_, unicodes_, has_seac_); @@ -79,36 +81,36 @@ struct hb_subset_accelerator_t hb_free (accel); } - hb_subset_accelerator_t (const hb_map_t& unicode_to_gid_, - const hb_multimap_t& gid_to_unicodes_, + hb_subset_accelerator_t (hb_face_t *source, + const hb_map_t& unicode_to_gid_, const hb_set_t& unicodes_, bool has_seac_) : unicode_to_gid(unicode_to_gid_), - gid_to_unicodes (gid_to_unicodes_), unicodes(unicodes_), cmap_cache(nullptr), destroy_cmap_cache(nullptr), has_seac(has_seac_), - cff_accelerator(nullptr), - destroy_cff_accelerator(nullptr) {} - - ~hb_subset_accelerator_t () + source(hb_face_reference (source)) { - if (cff_accelerator && destroy_cff_accelerator) - destroy_cff_accelerator ((void*) cff_accelerator); - - if (cmap_cache && destroy_cmap_cache) - destroy_cmap_cache ((void*) cmap_cache); + gid_to_unicodes.alloc (unicode_to_gid.get_population ()); + for (const auto &_ : unicode_to_gid) + { + auto unicode = _.first; + auto gid = _.second; + gid_to_unicodes.add (gid, unicode); + } } + HB_INTERNAL ~hb_subset_accelerator_t (); + // Generic mutable hb_mutex_t sanitized_table_cache_lock; mutable hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache; - const hb_map_t unicode_to_gid; - const hb_multimap_t gid_to_unicodes; - const hb_set_t unicodes; + hb_map_t unicode_to_gid; + hb_multimap_t gid_to_unicodes; + hb_set_t unicodes; // cmap const OT::SubtableUnicodesCache* cmap_cache; @@ -116,8 +118,6 @@ struct hb_subset_accelerator_t // CFF bool has_seac; - const CFF::cff_subset_accelerator_t* cff_accelerator; - hb_destroy_func_t destroy_cff_accelerator; // TODO(garretrieger): cumulative glyf checksum map @@ -128,6 +128,13 @@ struct hb_subset_accelerator_t unicodes.in_error () || sanitized_table_cache.in_error (); } + + hb_face_t *source; +#ifndef HB_NO_SUBSET_CFF + // These have to be immediately after source: + mutable hb_face_lazy_loader_t<OT::cff1_subset_accelerator_t, 1> cff1_accel; + mutable hb_face_lazy_loader_t<OT::cff2_subset_accelerator_t, 2> cff2_accel; +#endif }; diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.cc b/thirdparty/harfbuzz/src/hb-subset-cff-common.cc index 6e1b6f713d..5e4ea5fe7c 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff-common.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.cc @@ -68,24 +68,35 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, /* use hb_set to determine the subset of font dicts */ hb_set_t set; hb_codepoint_t prev_fd = CFF_UNDEF_CODE; - for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++) + hb_pair_t<unsigned, hb_codepoint_t> last_range {0, 0}; + auto it = hb_iter (plan->new_to_old_gid_list); + auto _ = *it; + for (hb_codepoint_t gid = 0; gid < subset_num_glyphs; gid++) { - hb_codepoint_t glyph; - hb_codepoint_t fd; - if (!plan->old_gid_for_new_gid (i, &glyph)) + hb_codepoint_t old_glyph; + if (gid == _.first) + { + old_glyph = _.second; + _ = *++it; + } + else { /* fonttools retains FDSelect & font dicts for missing glyphs. do the same */ - glyph = i; + old_glyph = gid; } - fd = src.get_fd (glyph); - set.add (fd); + if (old_glyph >= last_range.second) + last_range = src.get_fd_range (old_glyph); + unsigned fd = last_range.first; if (fd != prev_fd) { + set.add (fd); num_ranges++; prev_fd = fd; - code_pair_t pair = { fd, i }; - fdselect_ranges.push (pair); + fdselect_ranges.push (code_pair_t { fd, gid }); + + if (gid == old_glyph) + gid = hb_min (_.first - 1, last_range.second - 1); } } diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh index ff50b0e518..f54792648d 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh @@ -480,6 +480,7 @@ struct cff_subset_accelerator_t const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs) { cff_subset_accelerator_t* accel = (cff_subset_accelerator_t*) hb_malloc (sizeof(cff_subset_accelerator_t)); + if (unlikely (!accel)) return nullptr; new (accel) cff_subset_accelerator_t (original_blob, parsed_charstrings, parsed_global_subrs, @@ -510,15 +511,21 @@ struct cff_subset_accelerator_t original_blob = hb_blob_reference (original_blob_); } - ~cff_subset_accelerator_t() { + ~cff_subset_accelerator_t() + { hb_blob_destroy (original_blob); - hb_map_destroy (glyph_to_sid_map.get_relaxed ()); + auto *mapping = glyph_to_sid_map.get_relaxed (); + if (mapping) + { + mapping->~glyph_to_sid_map_t (); + hb_free (mapping); + } } parsed_cs_str_vec_t parsed_charstrings; parsed_cs_str_vec_t parsed_global_subrs; hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs; - mutable hb_atomic_ptr_t<hb_map_t> glyph_to_sid_map = nullptr; + mutable hb_atomic_ptr_t<glyph_to_sid_map_t> glyph_to_sid_map; private: hb_blob_t* original_blob; @@ -600,9 +607,8 @@ struct subr_remap_t : hb_inc_bimap_t * no optimization based on usage counts. fonttools doesn't appear doing that either. */ - resize (closure->get_population ()); - hb_codepoint_t old_num = HB_SET_VALUE_INVALID; - while (hb_set_next (closure, &old_num)) + alloc (closure->get_population ()); + for (auto old_num : *closure) add (old_num); if (get_population () < 1240) @@ -672,8 +678,8 @@ struct subr_subsetter_t { unsigned fd_count = acc.fdCount; const cff_subset_accelerator_t* cff_accelerator = nullptr; - if (plan->accelerator && plan->accelerator->cff_accelerator) { - cff_accelerator = plan->accelerator->cff_accelerator; + if (acc.cff_accelerator) { + cff_accelerator = acc.cff_accelerator; fd_count = cff_accelerator->parsed_local_subrs.length; } @@ -709,14 +715,13 @@ struct subr_subsetter_t } /* phase 1 & 2 */ - for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) + for (auto _ : plan->new_to_old_gid_list) { - hb_codepoint_t glyph; - if (!plan->old_gid_for_new_gid (i, &glyph)) - continue; + hb_codepoint_t new_glyph = _.first; + hb_codepoint_t old_glyph = _.second; - const hb_ubytes_t str = (*acc.charStrings)[glyph]; - unsigned int fd = acc.fdSelect->get_fd (glyph); + const hb_ubytes_t str = (*acc.charStrings)[old_glyph]; + unsigned int fd = acc.fdSelect->get_fd (old_glyph); if (unlikely (fd >= acc.fdCount)) return false; @@ -725,9 +730,9 @@ struct subr_subsetter_t // parsed string already exists in accelerator, copy it and move // on. if (cached_charstrings) - cached_charstrings[i] = &cff_accelerator->parsed_charstrings[glyph]; + cached_charstrings[new_glyph] = &cff_accelerator->parsed_charstrings[old_glyph]; else - parsed_charstrings[i] = cff_accelerator->parsed_charstrings[glyph]; + parsed_charstrings[new_glyph] = cff_accelerator->parsed_charstrings[old_glyph]; continue; } @@ -735,8 +740,8 @@ struct subr_subsetter_t ENV env (str, acc, fd); cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp (env); - parsed_charstrings[i].alloc (str.length); - subr_subset_param_t param (&parsed_charstrings[i], + parsed_charstrings[new_glyph].alloc (str.length); + subr_subset_param_t param (&parsed_charstrings[new_glyph], &parsed_global_subrs_storage, &parsed_local_subrs_storage[fd], &closures.global_closure, @@ -747,12 +752,12 @@ struct subr_subsetter_t return false; /* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */ - SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]); + SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[new_glyph]); /* mark hint ops and arguments for drop */ if ((plan->flags & HB_SUBSET_FLAGS_NO_HINTING) || plan->inprogress_accelerator) { - subr_subset_param_t param (&parsed_charstrings[i], + subr_subset_param_t param (&parsed_charstrings[new_glyph], &parsed_global_subrs_storage, &parsed_local_subrs_storage[fd], &closures.global_closure, @@ -760,11 +765,11 @@ struct subr_subsetter_t plan->flags & HB_SUBSET_FLAGS_NO_HINTING); drop_hints_param_t drop; - if (drop_hints_in_str (parsed_charstrings[i], param, drop)) + if (drop_hints_in_str (parsed_charstrings[new_glyph], param, drop)) { - parsed_charstrings[i].set_hint_dropped (); + parsed_charstrings[new_glyph].set_hint_dropped (); if (drop.vsindex_dropped) - parsed_charstrings[i].set_vsindex_dropped (); + parsed_charstrings[new_glyph].set_vsindex_dropped (); } } @@ -774,7 +779,7 @@ struct subr_subsetter_t * The compacting both saves memory and makes further operations * faster. */ - parsed_charstrings[i].compact (); + parsed_charstrings[new_glyph].compact (); } /* Since parsed strings were loaded from accelerator, we still need @@ -797,23 +802,40 @@ struct subr_subsetter_t bool encode_charstrings (str_buff_vec_t &buffArray, bool encode_prefix = true) const { - if (unlikely (!buffArray.resize_exact (plan->num_output_glyphs ()))) + unsigned num_glyphs = plan->num_output_glyphs (); + if (unlikely (!buffArray.resize_exact (num_glyphs))) return false; - for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) + hb_codepoint_t last = 0; + for (auto _ : plan->new_to_old_gid_list) { - hb_codepoint_t glyph; - if (!plan->old_gid_for_new_gid (i, &glyph)) - { - /* add an endchar only charstring for a missing glyph if CFF1 */ - if (endchar_op != OpCode_Invalid) buffArray.arrayZ[i].push (endchar_op); - continue; - } - unsigned int fd = acc.fdSelect->get_fd (glyph); + hb_codepoint_t gid = _.first; + hb_codepoint_t old_glyph = _.second; + + if (endchar_op != OpCode_Invalid) + for (; last < gid; last++) + { + // Hack to point vector to static string. + auto &b = buffArray.arrayZ[last]; + b.length = 1; + b.arrayZ = const_cast<unsigned char *>(endchar_str); + } + + last++; // Skip over gid + unsigned int fd = acc.fdSelect->get_fd (old_glyph); if (unlikely (fd >= acc.fdCount)) return false; - if (unlikely (!encode_str (get_parsed_charstring (i), fd, buffArray.arrayZ[i], encode_prefix))) + if (unlikely (!encode_str (get_parsed_charstring (gid), fd, buffArray.arrayZ[gid], encode_prefix))) return false; } + if (endchar_op != OpCode_Invalid) + for (; last < num_glyphs; last++) + { + // Hack to point vector to static string. + auto &b = buffArray.arrayZ[last]; + b.length = 1; + b.arrayZ = const_cast<unsigned char *>(endchar_str); + } + return true; } @@ -980,24 +1002,23 @@ struct subr_subsetter_t const hb_vector_t<parsed_cs_str_vec_t>& local_subrs) { closures.reset (); - for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) + for (auto _ : plan->new_to_old_gid_list) { - hb_codepoint_t glyph; - if (!plan->old_gid_for_new_gid (i, &glyph)) - continue; - unsigned int fd = acc.fdSelect->get_fd (glyph); + hb_codepoint_t new_glyph = _.first; + hb_codepoint_t old_glyph = _.second; + unsigned int fd = acc.fdSelect->get_fd (old_glyph); if (unlikely (fd >= acc.fdCount)) return false; // Note: const cast is safe here because the collect_subr_refs_in_str only performs a // closure and does not modify any of the charstrings. - subr_subset_param_t param (const_cast<parsed_cs_str_t*> (&get_parsed_charstring (i)), + subr_subset_param_t param (const_cast<parsed_cs_str_t*> (&get_parsed_charstring (new_glyph)), const_cast<parsed_cs_str_vec_t*> (&global_subrs), const_cast<parsed_cs_str_vec_t*> (&local_subrs[fd]), &closures.global_closure, &closures.local_closures[fd], plan->flags & HB_SUBSET_FLAGS_NO_HINTING); - collect_subr_refs_in_str (get_parsed_charstring (i), param); + collect_subr_refs_in_str (get_parsed_charstring (new_glyph), param); } return true; @@ -1105,14 +1126,11 @@ struct subr_subsetter_t compact_parsed_subrs (); - plan->inprogress_accelerator->cff_accelerator = + acc.cff_accelerator = cff_subset_accelerator_t::create(acc.blob, parsed_charstrings, parsed_global_subrs_storage, parsed_local_subrs_storage); - plan->inprogress_accelerator->destroy_cff_accelerator = - cff_subset_accelerator_t::destroy; - } const parsed_cs_str_t& get_parsed_charstring (unsigned i) const diff --git a/thirdparty/harfbuzz/src/hb-subset-cff1.cc b/thirdparty/harfbuzz/src/hb-subset-cff1.cc index 1d7ed6444a..e80d18d097 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff1.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff1.cc @@ -32,36 +32,59 @@ #include "hb-ot-cff1-table.hh" #include "hb-set.h" #include "hb-bimap.hh" -#include "hb-subset-cff1.hh" #include "hb-subset-plan.hh" #include "hb-subset-cff-common.hh" #include "hb-cff1-interp-cs.hh" using namespace CFF; -struct remap_sid_t : hb_inc_bimap_t +struct remap_sid_t { + unsigned get_population () const { return vector.length; } + + void alloc (unsigned size) + { + map.alloc (size); + vector.alloc (size, true); + } + + bool in_error () const + { return map.in_error () || vector.in_error (); } + unsigned int add (unsigned int sid) { - if ((sid != CFF_UNDEF_SID) && !is_std_std (sid)) - return offset_sid (hb_inc_bimap_t::add (unoffset_sid (sid))); - else + if (is_std_str (sid) || (sid == CFF_UNDEF_SID)) return sid; + + sid = unoffset_sid (sid); + unsigned v = next; + if (map.set (sid, v, false)) + { + vector.push (sid); + next++; + } + else + v = map.get (sid); // already exists + return offset_sid (v); } unsigned int operator[] (unsigned int sid) const { - if (is_std_std (sid) || (sid == CFF_UNDEF_SID)) + if (is_std_str (sid) || (sid == CFF_UNDEF_SID)) return sid; - else - return offset_sid (get (unoffset_sid (sid))); + + return offset_sid (map.get (unoffset_sid (sid))); } static const unsigned int num_std_strings = 391; - static bool is_std_std (unsigned int sid) { return sid < num_std_strings; } + static bool is_std_str (unsigned int sid) { return sid < num_std_strings; } static unsigned int offset_sid (unsigned int sid) { return sid + num_std_strings; } static unsigned int unoffset_sid (unsigned int sid) { return sid - num_std_strings; } + unsigned next = 0; + + hb_map_t map; + hb_vector_t<unsigned> vector; }; struct cff1_sub_table_info_t : cff_sub_table_info_t @@ -271,16 +294,17 @@ struct range_list_t : hb_vector_t<code_pair_t> /* replace the first glyph ID in the "glyph" field each range with a nLeft value */ bool complete (unsigned int last_glyph) { - bool two_byte = false; + hb_codepoint_t all_glyphs = 0; unsigned count = this->length; for (unsigned int i = count; i; i--) { code_pair_t &pair = arrayZ[i - 1]; unsigned int nLeft = last_glyph - pair.glyph - 1; - two_byte |= nLeft >= 0x100; + all_glyphs |= nLeft; last_glyph = pair.glyph; pair.glyph = nLeft; } + bool two_byte = all_glyphs >= 0x100; return two_byte; } }; @@ -391,8 +415,10 @@ struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs } }; -struct cff_subset_plan { - cff_subset_plan () +namespace OT { +struct cff1_subset_plan +{ + cff1_subset_plan () { for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++) topDictModSIDs[i] = CFF_UNDEF_SID; @@ -402,7 +428,7 @@ struct cff_subset_plan { { const Encoding *encoding = acc.encoding; unsigned int size0, size1; - hb_codepoint_t code, last_code = CFF_UNDEF_CODE; + unsigned code, last_code = CFF_UNDEF_CODE - 1; hb_vector_t<hb_codepoint_t> supp_codes; if (unlikely (!subset_enc_code_ranges.resize (0))) @@ -413,39 +439,42 @@ struct cff_subset_plan { supp_codes.init (); + code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID}; subset_enc_num_codes = plan->num_output_glyphs () - 1; unsigned int glyph; - for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++) + auto it = hb_iter (plan->new_to_old_gid_list); + if (it->first == 0) it++; + auto _ = *it; + for (glyph = 1; glyph < num_glyphs; glyph++) { - hb_codepoint_t old_glyph; - if (!plan->old_gid_for_new_gid (glyph, &old_glyph)) + hb_codepoint_t old_glyph; + if (glyph == _.first) + { + old_glyph = _.second; + _ = *++it; + } + else { - /* Retain the code for the old missing glyph ID */ + /* Retain the SID for the old missing glyph ID */ old_glyph = glyph; } - code = acc.glyph_to_code (old_glyph); + code = acc.glyph_to_code (old_glyph, &glyph_to_sid_cache); if (code == CFF_UNDEF_CODE) { subset_enc_num_codes = glyph - 1; break; } - if ((last_code == CFF_UNDEF_CODE) || (code != last_code + 1)) - { - code_pair_t pair = { code, glyph }; - subset_enc_code_ranges.push (pair); - } + if (code != last_code + 1) + subset_enc_code_ranges.push (code_pair_t {code, glyph}); last_code = code; if (encoding != &Null (Encoding)) { - hb_codepoint_t sid = acc.glyph_to_sid (old_glyph); + hb_codepoint_t sid = acc.glyph_to_sid (old_glyph, &glyph_to_sid_cache); encoding->get_supplement_codes (sid, supp_codes); for (unsigned int i = 0; i < supp_codes.length; i++) - { - code_pair_t pair = { supp_codes[i], sid }; - subset_enc_supp_codes.push (pair); - } + subset_enc_supp_codes.push (code_pair_t {supp_codes[i], sid}); } } supp_codes.fini (); @@ -462,65 +491,95 @@ struct cff_subset_plan { subset_enc_format = 1; } - void plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan) + bool plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan) { unsigned int size0, size_ranges; - hb_codepoint_t sid, last_sid = CFF_UNDEF_CODE; + unsigned last_sid = CFF_UNDEF_CODE - 1; if (unlikely (!subset_charset_ranges.resize (0))) { plan->check_success (false); - return; + return false; } - hb_map_t *glyph_to_sid_map = (plan->accelerator && plan->accelerator->cff_accelerator) ? - plan->accelerator->cff_accelerator->glyph_to_sid_map : - nullptr; + code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID}; + + unsigned num_glyphs = plan->num_output_glyphs (); + + if (unlikely (!subset_charset_ranges.alloc (hb_min (num_glyphs, + acc.num_charset_entries)))) + { + plan->check_success (false); + return false; + } + + glyph_to_sid_map_t *glyph_to_sid_map = acc.cff_accelerator ? + acc.cff_accelerator->glyph_to_sid_map.get_acquire () : + nullptr; bool created_map = false; - if (!glyph_to_sid_map && - ((plan->accelerator && plan->accelerator->cff_accelerator) || - plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.)) + if (!glyph_to_sid_map && acc.cff_accelerator) { created_map = true; glyph_to_sid_map = acc.create_glyph_to_sid_map (); } - unsigned int glyph; - for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++) + auto it = hb_iter (plan->new_to_old_gid_list); + if (it->first == 0) it++; + auto _ = *it; + bool not_is_cid = !acc.is_CID (); + bool skip = !not_is_cid && glyph_to_sid_map; + if (not_is_cid) + sidmap.alloc (num_glyphs); + for (hb_codepoint_t glyph = 1; glyph < num_glyphs; glyph++) { - hb_codepoint_t old_glyph; - if (!plan->old_gid_for_new_gid (glyph, &old_glyph)) + hb_codepoint_t old_glyph; + if (glyph == _.first) + { + old_glyph = _.second; + _ = *++it; + } + else { /* Retain the SID for the old missing glyph ID */ old_glyph = glyph; } - sid = glyph_to_sid_map ? glyph_to_sid_map->get (old_glyph) : acc.glyph_to_sid (old_glyph); + unsigned sid = glyph_to_sid_map ? + glyph_to_sid_map->arrayZ[old_glyph].code : + acc.glyph_to_sid (old_glyph, &glyph_to_sid_cache); - if (!acc.is_CID ()) + if (not_is_cid) sid = sidmap.add (sid); - if ((last_sid == CFF_UNDEF_CODE) || (sid != last_sid + 1)) + if (sid != last_sid + 1) { - code_pair_t pair = { sid, glyph }; - subset_charset_ranges.push (pair); + subset_charset_ranges.push (code_pair_t {sid, glyph}); + + if (glyph == old_glyph && skip) + { + glyph = hb_min (_.first - 1, glyph_to_sid_map->arrayZ[old_glyph].glyph); + sid += glyph - old_glyph; + } } last_sid = sid; } if (created_map) { - if (!(plan->accelerator && plan->accelerator->cff_accelerator) || - !plan->accelerator->cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map)) - hb_map_destroy (glyph_to_sid_map); + if ((!plan->accelerator && acc.cff_accelerator) || + !acc.cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map)) + { + glyph_to_sid_map->~glyph_to_sid_map_t (); + hb_free (glyph_to_sid_map); + } } - bool two_byte = subset_charset_ranges.complete (glyph); + bool two_byte = subset_charset_ranges.complete (num_glyphs); - size0 = Charset0::min_size + HBUINT16::static_size * (plan->num_output_glyphs () - 1); + size0 = Charset0::get_size (plan->num_output_glyphs ()); if (!two_byte) - size_ranges = Charset1::min_size + Charset1_Range::static_size * subset_charset_ranges.length; + size_ranges = Charset1::get_size_for_ranges (subset_charset_ranges.length); else - size_ranges = Charset2::min_size + Charset2_Range::static_size * subset_charset_ranges.length; + size_ranges = Charset2::get_size_for_ranges (subset_charset_ranges.length); if (size0 < size_ranges) subset_charset_format = 0; @@ -528,19 +587,18 @@ struct cff_subset_plan { subset_charset_format = 1; else subset_charset_format = 2; + + return true; } bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc) { - sidmap.reset (); - for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++) { unsigned int sid = acc.topDict.nameSIDs[i]; if (sid != CFF_UNDEF_SID) { - (void)sidmap.add (sid); - topDictModSIDs[i] = sidmap[sid]; + topDictModSIDs[i] = sidmap.add (sid); } } @@ -564,19 +622,18 @@ struct cff_subset_plan { drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING; desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE; - /* check whether the subset renumbers any glyph IDs */ - gid_renum = false; - for (hb_codepoint_t new_glyph = 0; new_glyph < plan->num_output_glyphs (); new_glyph++) - { - if (!plan->old_gid_for_new_gid(new_glyph, &old_glyph)) - continue; - if (new_glyph != old_glyph) { - gid_renum = true; - break; + subset_charset = !acc.is_predef_charset (); + if (!subset_charset) + /* check whether the subset renumbers any glyph IDs */ + for (const auto &_ : plan->new_to_old_gid_list) + { + if (_.first != _.second) + { + subset_charset = true; + break; + } } - } - subset_charset = gid_renum || !acc.is_predef_charset (); subset_encoding = !acc.is_CID() && !acc.is_predef_encoding (); /* top dict INDEX */ @@ -618,7 +675,8 @@ struct cff_subset_plan { if (unlikely (sidmap.get_population () > 0x8000)) /* assumption: a dict won't reference that many strings */ return false; - if (subset_charset) plan_subset_charset (acc, plan); + if (subset_charset && !plan_subset_charset (acc, plan)) + return false; topdict_mod.reassignSIDs (sidmap); } @@ -682,8 +740,9 @@ struct cff_subset_plan { ; } - return ((subset_charstrings.length == plan->num_output_glyphs ()) - && (fontdicts_mod.length == subset_fdcount)); + return !plan->in_error () && + (subset_charstrings.length == plan->num_output_glyphs ()) && + (fontdicts_mod.length == subset_fdcount); } cff1_top_dict_values_mod_t topdict_mod; @@ -722,24 +781,22 @@ struct cff_subset_plan { bool desubroutinize = false; }; +} // namespace OT -static bool _serialize_cff1 (hb_serialize_context_t *c, - cff_subset_plan &plan, - const OT::cff1::accelerator_subset_t &acc, - unsigned int num_glyphs) +bool +OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c, + struct OT::cff1_subset_plan &plan) const { /* private dicts & local subrs */ - for (int i = (int)acc.privateDicts.length; --i >= 0 ;) + for (int i = (int) privateDicts.length; --i >= 0 ;) { if (plan.fdmap.has (i)) { objidx_t subrs_link = 0; if (plan.subset_localsubrs[i].length > 0) { - CFF1Subrs *dest = c->start_embed <CFF1Subrs> (); - if (unlikely (!dest)) return false; - c->push (); - if (likely (dest && dest->serialize (c, plan.subset_localsubrs[i]))) + auto *dest = c->push <CFF1Subrs> (); + if (likely (dest->serialize (c, plan.subset_localsubrs[i]))) subrs_link = c->pop_pack (); else { @@ -748,12 +805,10 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, } } - PrivateDict *pd = c->start_embed<PrivateDict> (); - if (unlikely (!pd)) return false; - c->push (); + auto *pd = c->push<PrivateDict> (); cff1_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints); /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */ - if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link))) + if (likely (pd->serialize (c, privateDicts[i], privSzr, subrs_link))) { unsigned fd = plan.fdmap[i]; plan.fontdicts_mod[fd].privateDictInfo.size = c->length (); @@ -767,21 +822,20 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, } } - if (!acc.is_CID ()) + if (!is_CID ()) plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo; /* CharStrings */ { c->push<CFF1CharStrings> (); - unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings); + unsigned data_size = 0; + unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size); if (unlikely (!c->start_zerocopy (total_size))) return false; - CFF1CharStrings *cs = c->start_embed<CFF1CharStrings> (); - if (unlikely (!cs)) return false; - - if (likely (cs->serialize (c, plan.subset_charstrings))) + auto *cs = c->start_embed<CFF1CharStrings> (); + if (likely (cs->serialize (c, plan.subset_charstrings, &data_size))) plan.info.char_strings_link = c->pop_pack (false); else { @@ -791,11 +845,9 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, } /* FDArray (FD Index) */ - if (acc.fdArray != &Null (CFF1FDArray)) + if (fdArray != &Null (CFF1FDArray)) { - CFF1FDArray *fda = c->start_embed<CFF1FDArray> (); - if (unlikely (!fda)) return false; - c->push (); + auto *fda = c->push<CFF1FDArray> (); cff1_font_dict_op_serializer_t fontSzr; auto it = + hb_zip (+ hb_iter (plan.fontdicts_mod), + hb_iter (plan.fontdicts_mod)); if (likely (fda->serialize (c, it, fontSzr))) @@ -808,10 +860,10 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, } /* FDSelect */ - if (acc.fdSelect != &Null (CFF1FDSelect)) + if (fdSelect != &Null (CFF1FDSelect)) { c->push (); - if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *acc.fdSelect, acc.fdCount, + if (likely (hb_serialize_cff_fdselect (c, plan.num_glyphs, *fdSelect, fdCount, plan.subset_fdselect_format, plan.info.fd_select.size, plan.subset_fdselect_ranges))) plan.info.fd_select.link = c->pop_pack (); @@ -825,9 +877,7 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, /* Charset */ if (plan.subset_charset) { - Charset *dest = c->start_embed<Charset> (); - if (unlikely (!dest)) return false; - c->push (); + auto *dest = c->push<Charset> (); if (likely (dest->serialize (c, plan.subset_charset_format, plan.num_glyphs, @@ -843,9 +893,7 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, /* Encoding */ if (plan.subset_encoding) { - Encoding *dest = c->start_embed<Encoding> (); - if (unlikely (!dest)) return false; - c->push (); + auto *dest = c->push<Encoding> (); if (likely (dest->serialize (c, plan.subset_enc_format, plan.subset_enc_num_codes, @@ -861,9 +909,7 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, /* global subrs */ { - c->push (); - CFF1Subrs *dest = c->start_embed <CFF1Subrs> (); - if (unlikely (!dest)) return false; + auto *dest = c->push <CFF1Subrs> (); if (likely (dest->serialize (c, plan.subset_globalsubrs))) c->pop_pack (false); else @@ -875,10 +921,9 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, /* String INDEX */ { - CFF1StringIndex *dest = c->start_embed<CFF1StringIndex> (); - if (unlikely (!dest)) return false; - c->push (); - if (likely (dest->serialize (c, *acc.stringIndex, plan.sidmap))) + auto *dest = c->push<CFF1StringIndex> (); + if (likely (!plan.sidmap.in_error () && + dest->serialize (c, *stringIndex, plan.sidmap.vector))) c->pop_pack (); else { @@ -898,14 +943,12 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, cff->offSize = 4; /* unused? */ /* name INDEX */ - if (unlikely (!(*acc.nameIndex).copy (c))) return false; + if (unlikely (!c->embed (*nameIndex))) return false; /* top dict INDEX */ { /* serialize singleton TopDict */ - TopDict *top = c->start_embed<TopDict> (); - if (!top) return false; - c->push (); + auto *top = c->push<TopDict> (); cff1_top_dict_op_serializer_t topSzr; unsigned top_size = 0; top_dict_modifiers_t modifier (plan.info, plan.topDictModSIDs); @@ -920,36 +963,23 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, return false; } /* serialize INDEX header for above */ - CFF1Index *dest = c->start_embed<CFF1Index> (); - if (!dest) return false; - return dest->serialize_header (c, hb_iter (hb_array_t<unsigned> (&top_size, 1))); + auto *dest = c->start_embed<CFF1Index> (); + return dest->serialize_header (c, hb_iter (&top_size, 1), top_size); } } -static bool -_hb_subset_cff1 (const OT::cff1::accelerator_subset_t &acc, - hb_subset_context_t *c) +bool +OT::cff1::accelerator_subset_t::subset (hb_subset_context_t *c) const { - cff_subset_plan cff_plan; + cff1_subset_plan cff_plan; - if (unlikely (!cff_plan.create (acc, c->plan))) + if (unlikely (!cff_plan.create (*this, c->plan))) { DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cff subsetting plan."); return false; } - return _serialize_cff1 (c->serializer, cff_plan, acc, c->plan->num_output_glyphs ()); -} - -bool -hb_subset_cff1 (hb_subset_context_t *c) -{ - OT::cff1::accelerator_subset_t acc; - acc.init (c->plan->source); - bool result = likely (acc.is_valid ()) && _hb_subset_cff1 (acc, c); - acc.fini (); - - return result; + return serialize (c->serializer, cff_plan); } diff --git a/thirdparty/harfbuzz/src/hb-subset-cff2.cc b/thirdparty/harfbuzz/src/hb-subset-cff2.cc index 8ab4620194..3c52fb9c2c 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff2.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff2.cc @@ -31,7 +31,6 @@ #include "hb-open-type.hh" #include "hb-ot-cff2-table.hh" #include "hb-set.h" -#include "hb-subset-cff2.hh" #include "hb-subset-plan.hh" #include "hb-subset-cff-common.hh" #include "hb-cff2-interp-cs.hh" @@ -422,11 +421,17 @@ struct cff2_private_dict_op_serializer_t : op_serializer_t }; +namespace OT { struct cff2_subset_plan { bool create (const OT::cff2::accelerator_subset_t &acc, hb_subset_plan_t *plan) { + /* make sure notdef is first */ + hb_codepoint_t old_glyph; + if (!plan->old_gid_for_new_gid (0, &old_glyph) || (old_glyph != 0)) return false; + + num_glyphs = plan->num_output_glyphs (); orig_fdcount = acc.fdArray->count; drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING; @@ -489,6 +494,7 @@ struct cff2_subset_plan cff2_sub_table_info_t info; + unsigned int num_glyphs; unsigned int orig_fdcount = 0; unsigned int subset_fdcount = 1; unsigned int subset_fdselect_size = 0; @@ -505,18 +511,18 @@ struct cff2_subset_plan bool drop_hints = false; bool desubroutinize = false; }; +} // namespace OT -static bool _serialize_cff2 (hb_serialize_context_t *c, - cff2_subset_plan &plan, - const OT::cff2::accelerator_subset_t &acc, - unsigned int num_glyphs, - hb_array_t<int> normalized_coords) +bool +OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, + struct cff2_subset_plan &plan, + hb_array_t<int> normalized_coords) const { /* private dicts & local subrs */ hb_vector_t<table_info_t> private_dict_infos; if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false; - for (int i = (int)acc.privateDicts.length; --i >= 0 ;) + for (int i = (int)privateDicts.length; --i >= 0 ;) { if (plan.fdmap.has (i)) { @@ -524,9 +530,7 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, if (plan.subset_localsubrs[i].length > 0) { - CFF2Subrs *dest = c->start_embed <CFF2Subrs> (); - if (unlikely (!dest)) return false; - c->push (); + auto *dest = c->push <CFF2Subrs> (); if (likely (dest->serialize (c, plan.subset_localsubrs[i]))) subrs_link = c->pop_pack (false); else @@ -535,12 +539,10 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, return false; } } - PrivateDict *pd = c->start_embed<PrivateDict> (); - if (unlikely (!pd)) return false; - c->push (); + auto *pd = c->push<PrivateDict> (); cff2_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints, plan.pinned, - acc.varStore, normalized_coords); - if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link))) + varStore, normalized_coords); + if (likely (pd->serialize (c, privateDicts[i], privSzr, subrs_link))) { unsigned fd = plan.fdmap[i]; private_dict_infos[fd].size = c->length (); @@ -558,14 +560,13 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, { c->push (); - unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings); + unsigned data_size = 0; + unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size); if (unlikely (!c->start_zerocopy (total_size))) return false; - CFF2CharStrings *cs = c->start_embed<CFF2CharStrings> (); - if (unlikely (!cs)) return false; - - if (likely (cs->serialize (c, plan.subset_charstrings))) + auto *cs = c->start_embed<CFF2CharStrings> (); + if (likely (cs->serialize (c, plan.subset_charstrings, &data_size))) plan.info.char_strings_link = c->pop_pack (false); else { @@ -575,10 +576,10 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, } /* FDSelect */ - if (acc.fdSelect != &Null (CFF2FDSelect)) + if (fdSelect != &Null (CFF2FDSelect)) { c->push (); - if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect, + if (likely (hb_serialize_cff_fdselect (c, plan.num_glyphs, *(const FDSelect *)fdSelect, plan.orig_fdcount, plan.subset_fdselect_format, plan.subset_fdselect_size, plan.subset_fdselect_ranges))) @@ -592,27 +593,32 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, /* FDArray (FD Index) */ { - c->push (); - CFF2FDArray *fda = c->start_embed<CFF2FDArray> (); - if (unlikely (!fda)) return false; + auto *fda = c->push<CFF2FDArray> (); cff_font_dict_op_serializer_t fontSzr; auto it = - + hb_zip (+ hb_iter (acc.fontDicts) + + hb_zip (+ hb_iter (fontDicts) | hb_filter ([&] (const cff2_font_dict_values_t &_) - { return plan.fdmap.has (&_ - &acc.fontDicts[0]); }), + { return plan.fdmap.has (&_ - &fontDicts[0]); }), hb_iter (private_dict_infos)) ; - if (unlikely (!fda->serialize (c, it, fontSzr))) return false; + if (unlikely (!fda->serialize (c, it, fontSzr))) + { + c->pop_discard (); + return false; + } plan.info.fd_array_link = c->pop_pack (false); } /* variation store */ - if (acc.varStore != &Null (CFF2VariationStore) && + if (varStore != &Null (CFF2VariationStore) && !plan.pinned) { - c->push (); - CFF2VariationStore *dest = c->start_embed<CFF2VariationStore> (); - if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false; + auto *dest = c->push<CFF2VariationStore> (); + if (unlikely (!dest->serialize (c, varStore))) + { + c->pop_discard (); + return false; + } plan.info.var_store_link = c->pop_pack (false); } @@ -628,34 +634,25 @@ static bool _serialize_cff2 (hb_serialize_context_t *c, { TopDict &dict = cff2 + cff2->topDict; cff2_top_dict_op_serializer_t topSzr; - if (unlikely (!dict.serialize (c, acc.topDict, topSzr, plan.info))) return false; + if (unlikely (!dict.serialize (c, topDict, topSzr, plan.info))) return false; cff2->topDictSize = c->head - (const char *)&dict; } /* global subrs */ { - CFF2Subrs *dest = c->start_embed <CFF2Subrs> (); - if (unlikely (!dest)) return false; + auto *dest = c->start_embed <CFF2Subrs> (); return dest->serialize (c, plan.subset_globalsubrs); } } -static bool -_hb_subset_cff2 (const OT::cff2::accelerator_subset_t &acc, - hb_subset_context_t *c) +bool +OT::cff2::accelerator_subset_t::subset (hb_subset_context_t *c) const { cff2_subset_plan cff2_plan; - if (unlikely (!cff2_plan.create (acc, c->plan))) return false; - return _serialize_cff2 (c->serializer, cff2_plan, acc, c->plan->num_output_glyphs (), - c->plan->normalized_coords.as_array ()); -} - -bool -hb_subset_cff2 (hb_subset_context_t *c) -{ - OT::cff2::accelerator_subset_t acc (c->plan->source); - return acc.is_valid () && _hb_subset_cff2 (acc, c); + if (unlikely (!cff2_plan.create (*this, c->plan))) return false; + return serialize (c->serializer, cff2_plan, + c->plan->normalized_coords.as_array ()); } #endif diff --git a/thirdparty/harfbuzz/src/hb-subset-input.cc b/thirdparty/harfbuzz/src/hb-subset-input.cc index 465af50814..e6b23df704 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.cc +++ b/thirdparty/harfbuzz/src/hb-subset-input.cc @@ -438,7 +438,8 @@ hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - return input->axes_location.set (axis_tag, axis_info.default_value); + float default_val = axis_info.default_value; + return input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val)); } /** @@ -468,8 +469,52 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, return false; float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value); - return input->axes_location.set (axis_tag, val); + return input->axes_location.set (axis_tag, Triple (val, val, val)); } + +#ifdef HB_EXPERIMENTAL_API +/** + * hb_subset_input_set_axis_range: (skip) + * @input: a #hb_subset_input_t object. + * @face: a #hb_face_t object. + * @axis_tag: Tag of the axis + * @axis_min_value: Minimum value of the axis variation range to set + * @axis_max_value: Maximum value of the axis variation range to set + * + * Restricting the range of variation on an axis in the given subset input object. + * New min/max values will be clamped if they're not within the fvar axis range. + * If the fvar axis default value is not within the new range, the new default + * value will be changed to the new min or max value, whichever is closer to the fvar + * axis default. + * + * Note: input min value can not be bigger than input max value + * Note: currently this API does not support changing axis limits yet.It'd be only + * used internally for setting axis limits in the internal data structures + * + * Return value: `true` if success, `false` otherwise + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_bool_t +hb_subset_input_set_axis_range (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag, + float axis_min_value, + float axis_max_value) +{ + if (axis_min_value > axis_max_value) + return false; + + hb_ot_var_axis_info_t axis_info; + if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) + return false; + + float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value); + float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value); + float new_default_val = hb_clamp(axis_info.default_value, new_min_val, new_max_val); + return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val)); +} +#endif #endif /** diff --git a/thirdparty/harfbuzz/src/hb-subset-input.hh b/thirdparty/harfbuzz/src/hb-subset-input.hh index 1970f795b9..6ae311e613 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.hh +++ b/thirdparty/harfbuzz/src/hb-subset-input.hh @@ -35,6 +35,7 @@ #include "hb-set.hh" #include "hb-cplusplus.hh" #include "hb-font.hh" +#include "hb-subset-instancer-solver.hh" struct hb_ot_name_record_ids_t { @@ -118,7 +119,7 @@ struct hb_subset_input_t // If set loca format will always be the long version. bool force_long_loca = false; - hb_hashmap_t<hb_tag_t, float> axes_location; + hb_hashmap_t<hb_tag_t, Triple> axes_location; hb_map_t glyph_map; #ifdef HB_EXPERIMENTAL_API hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> name_table_overrides; diff --git a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc index 7a2735c529..c698d944ce 100644 --- a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc +++ b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#include "hb.hh" +#include "hb-subset-instancer-solver.hh" /* This file is a straight port of the following: * @@ -35,26 +35,6 @@ constexpr static float EPSILON = 1.f / (1 << 14); constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14); -struct Triple { - - Triple () : - minimum (0.f), middle (0.f), maximum (0.f) {} - - Triple (float minimum_, float middle_, float maximum_) : - minimum (minimum_), middle (middle_), maximum (maximum_) {} - - bool operator == (const Triple &o) const - { - return minimum == o.minimum && - middle == o.middle && - maximum == o.maximum; - } - - float minimum; - float middle; - float maximum; -}; - static inline Triple _reverse_negate(const Triple &v) { return {-v.maximum, -v.middle, -v.minimum}; } @@ -82,10 +62,6 @@ static inline float supportScalar (float coord, const Triple &tent) return (end - coord) / (end - peak); } - -using result_item_t = hb_pair_t<float, Triple>; -using result_t = hb_vector_t<result_item_t>; - static inline result_t _solve (Triple tent, Triple axisLimit, bool negative = false) { @@ -195,9 +171,9 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) if (gain > outGain) { // Crossing point on the axis. - float crossing = peak + ((1 - gain) * (upper - peak) / (1 - outGain)); + float crossing = peak + (1 - gain) * (upper - peak); - Triple loc{peak, peak, crossing}; + Triple loc{axisDef, peak, crossing}; float scalar = 1.f; // The part before the crossing point. @@ -213,7 +189,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) if (upper >= axisMax) { Triple loc {crossing, axisMax, axisMax}; - float scalar = supportScalar (axisMax, tent); + float scalar = outGain; out.push (hb_pair (scalar - gain, loc)); } @@ -247,89 +223,83 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // Eternity justify. Triple loc2 {upper, axisMax, axisMax}; - float scalar2 = 1.f; // supportScalar({"tag": axisMax}, {"tag": tent}) + float scalar2 = 0.f; out.push (hb_pair (scalar1 - gain, loc1)); out.push (hb_pair (scalar2 - gain, loc2)); } } - /* Case 3: Outermost limit still fits within F2Dot14 bounds; - * we keep deltas as is and only scale the axes bounds. Deltas beyond -1.0 - * or +1.0 will never be applied as implementations must clamp to that range. - * - * A second tent is needed for cases when gain is positive, though we add it - * unconditionally and it will be dropped because scalar ends up 0. - * - * TODO: See if we can just move upper closer to adjust the slope, instead of - * second tent. - * - * | peak | - * 1.........|............o...|.................. - * | /x\ | - * | /xxx\ | - * | /xxxxx\| - * | /xxxxxxx+ - * | /xxxxxxxx|\ - * 0---|-----|------oxxxxxxxxx|xo---------------1 - * axisMin | lower | upper - * | | - * axisDef axisMax - */ - else if (axisDef + (axisMax - axisDef) * 2 >= upper) + else { - if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper) - { - // we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience - upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14; - assert (peak < upper); - } - // Special-case if peak is at axisMax. if (axisMax == peak) upper = peak; - Triple loc1 {hb_max (axisDef, lower), peak, upper}; - float scalar1 = 1.f; + /* Case 3: + * we keep deltas as is and only scale the axis upper to achieve + * the desired new tent if feasible. + * + * peak + * 1.....................o.................... + * / \_| + * ..................../....+_.........outGain + * / | \ + * gain..............+......|..+_............. + * /| | | \ + * 0---|-----------o | | | o----------1 + * axisMin lower| | | upper + * | | newUpper + * axisDef axisMax + */ + float newUpper = peak + (1 - gain) * (upper - peak); + // I feel like the first condition is always true because + // outGain >= gain. + if (axisMax <= newUpper && newUpper <= axisDef + (axisMax - axisDef) * 2) + { + upper = newUpper; + if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper) + { + // we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience + upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14; + assert (peak < upper); + } - Triple loc2 {peak, upper, upper}; - float scalar2 = 0.f; + Triple loc {hb_max (axisDef, lower), peak, upper}; + float scalar = 1.f; - // Don't add a dirac delta! - if (axisDef < upper) - out.push (hb_pair (scalar1 - gain, loc1)); - if (peak < upper) - out.push (hb_pair (scalar2 - gain, loc2)); - } + out.push (hb_pair (scalar - gain, loc)); + } - /* Case 4: New limit doesn't fit; we need to chop into two tents, - * because the shape of a triangle with part of one side cut off - * cannot be represented as a triangle itself. - * - * | peak | - * 1.........|......o.|................... - * | /x\| - * | |xxy|\_ - * | /xxxy| \_ - * | |xxxxy| \_ - * | /xxxxy| \_ - * 0---|-----|-oxxxxxx| o----------1 - * axisMin | lower | upper - * | | - * axisDef axisMax - */ - else - { - Triple loc1 {hb_max (axisDef, lower), peak, axisMax}; - float scalar1 = 1.f; + /* Case 4: New limit doesn't fit; we need to chop into two tents, + * because the shape of a triangle with part of one side cut off + * cannot be represented as a triangle itself. + * + * | peak | + * 1.........|......o.|.................... + * ..........|...../x\|.............outGain + * | |xxy|\_ + * | /xxxy| \_ + * | |xxxxy| \_ + * | /xxxxy| \_ + * 0---|-----|-oxxxxxx| o----------1 + * axisMin | lower | upper + * | | + * axisDef axisMax + */ + else + { + Triple loc1 {hb_max (axisDef, lower), peak, axisMax}; + float scalar1 = 1.f; - Triple loc2 {peak, axisMax, axisMax}; - float scalar2 = supportScalar (axisMax, tent); + Triple loc2 {peak, axisMax, axisMax}; + float scalar2 = outGain; - out.push (hb_pair (scalar1 - gain, loc1)); - // Don't add a dirac delta! - if (peak < axisMax) - out.push (hb_pair (scalar2 - gain, loc2)); + out.push (hb_pair (scalar1 - gain, loc1)); + // Don't add a dirac delta! + if (peak < axisMax) + out.push (hb_pair (scalar2 - gain, loc2)); + } } /* Now, the negative side @@ -422,19 +392,6 @@ static inline float normalizeValue (float v, const Triple &triple, bool extrapol } } -/* Given a tuple (lower,peak,upper) "tent" and new axis limits - * (axisMin,axisDefault,axisMax), solves how to represent the tent - * under the new axis configuration. All values are in normalized - * -1,0,+1 coordinate system. Tent values can be outside this range. - * - * Return value: a list of tuples. Each tuple is of the form - * (scalar,tent), where scalar is a multipler to multiply any - * delta-sets by, and tent is a new tent for that output delta-set. - * If tent value is Triple{}, that is a special deltaset that should - * be always-enabled (called "gain"). - */ -HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit); - result_t rebase_tent (Triple tent, Triple axisLimit) { @@ -460,5 +417,5 @@ rebase_tent (Triple tent, Triple axisLimit) Triple{n (t.minimum), n (t.middle), n (t.maximum)})); } - return sols; + return out; } diff --git a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh new file mode 100644 index 0000000000..b1f8594937 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh @@ -0,0 +1,90 @@ +/* + * Copyright © 2023 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_SUBSET_INSTANCER_SOLVER_HH +#define HB_SUBSET_INSTANCER_SOLVER_HH + +#include "hb.hh" + +struct Triple { + + Triple () : + minimum (0.f), middle (0.f), maximum (0.f) {} + + Triple (float minimum_, float middle_, float maximum_) : + minimum (minimum_), middle (middle_), maximum (maximum_) {} + + bool operator == (const Triple &o) const + { + return minimum == o.minimum && + middle == o.middle && + maximum == o.maximum; + } + + bool operator != (const Triple o) const + { return !(*this == o); } + + bool is_point () const + { return minimum == middle && middle == maximum; } + + bool contains (float point) const + { return minimum <= point && point <= maximum; } + + /* from hb_array_t hash ()*/ + uint32_t hash () const + { + uint32_t current = /*cbf29ce4*/0x84222325; + current = current ^ hb_hash (minimum); + current = current * 16777619; + + current = current ^ hb_hash (middle); + current = current * 16777619; + + current = current ^ hb_hash (maximum); + current = current * 16777619; + return current; + } + + float minimum; + float middle; + float maximum; +}; + +using result_item_t = hb_pair_t<float, Triple>; +using result_t = hb_vector_t<result_item_t>; + +/* Given a tuple (lower,peak,upper) "tent" and new axis limits + * (axisMin,axisDefault,axisMax), solves how to represent the tent + * under the new axis configuration. All values are in normalized + * -1,0,+1 coordinate system. Tent values can be outside this range. + * + * Return value: a list of tuples. Each tuple is of the form + * (scalar,tent), where scalar is a multipler to multiply any + * delta-sets by, and tent is a new tent for that output delta-set. + * If tent value is Triple{}, that is a special deltaset that should + * be always-enabled (called "gain"). + */ +HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit); + +#endif /* HB_SUBSET_INSTANCER_SOLVER_HH */ diff --git a/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh b/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh index acf508c32d..be29e67ecb 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh @@ -33,7 +33,9 @@ // For each cp that we'd like to retain maps to the corresponding gid. HB_SUBSET_PLAN_MEMBER (hb_set_t, unicodes) -HB_SUBSET_PLAN_MEMBER (hb_sorted_vector_t E(<hb_pair_t<hb_codepoint_t, hb_codepoint_t>>), unicode_to_new_gid_list) +HB_SUBSET_PLAN_MEMBER (hb_sorted_vector_t<hb_codepoint_pair_t>, unicode_to_new_gid_list) + +HB_SUBSET_PLAN_MEMBER (hb_sorted_vector_t<hb_codepoint_pair_t>, new_to_old_gid_list) // name_ids we would like to retain HB_SUBSET_PLAN_MEMBER (hb_set_t, name_ids) @@ -97,12 +99,12 @@ HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_inc_bimap_t>, gdef_varstore_inner_maps) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, hb::unique_ptr<hb_blob_t>>), sanitized_table_cache) -//normalized axes location map -HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, int>), axes_location) +//normalized axes range map +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, Triple>), axes_location) HB_SUBSET_PLAN_MEMBER (hb_vector_t<int>, normalized_coords) -//user specified axes location map -HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, float>), user_axes_location) +//user specified axes range map +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, Triple>), user_axes_location) //retained old axis index -> new axis index mapping in fvar axis array HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_index_map) @@ -115,9 +117,9 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, hb_pair_t E(<unsi //vmtx metrics map: new gid->(advance, lsb) HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, hb_pair_t E(<unsigned, int>)>), vmtx_map) //boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin -HB_SUBSET_PLAN_MEMBER (mutable hb_map_t, bounds_width_map) +HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_width_vec) //boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin -HB_SUBSET_PLAN_MEMBER (mutable hb_map_t, bounds_height_map) +HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_height_vec) #ifdef HB_EXPERIMENTAL_API // name table overrides map: hb_ot_name_record_ids_t-> name string new value or diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 791f92d02d..9a00de3e60 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -48,10 +48,24 @@ using OT::Layout::GSUB; using OT::Layout::GPOS; + +hb_subset_accelerator_t::~hb_subset_accelerator_t () +{ + if (cmap_cache && destroy_cmap_cache) + destroy_cmap_cache ((void*) cmap_cache); + +#ifndef HB_NO_SUBSET_CFF + cff1_accel.fini (); + cff2_accel.fini (); +#endif + hb_face_destroy (source); +} + + typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline bool -_add_cff_seac_components (const OT::cff1::accelerator_t &cff, +_add_cff_seac_components (const OT::cff1::accelerator_subset_t &cff, hb_codepoint_t gid, hb_set_t *gids_to_retain) { @@ -135,7 +149,8 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, hb_set_t *lookup_indices, /* OUT */ hb_set_t *feature_indices, /* OUT */ hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map, /* OUT */ - hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map /* OUT */) + hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map, /* OUT */ + bool& insert_catch_all_feature_variation_record) { unsigned num_features = table.get_feature_count (); hb_vector_t<hb_tag_t> features; @@ -171,8 +186,11 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, &plan->axes_location, feature_record_cond_idx_map, feature_substitutes_map, + insert_catch_all_feature_variation_record, feature_indices, - true, + false, + false, + false, 0, &conditionset_map }; @@ -283,7 +301,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, hb_map_t *features, script_langsys_map *langsys_map, hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map, - hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map) + hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map, + bool& insert_catch_all_feature_variation_record) { hb_blob_ptr_t<T> table = plan->source_table<T> (); hb_tag_t table_tag = table->tableTag; @@ -293,7 +312,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, &lookup_indices, &feature_indices, feature_record_cond_idx_map, - feature_substitutes_map); + feature_substitutes_map, + insert_catch_all_feature_variation_record); if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) hb_ot_layout_lookups_substitute_closure (plan->source, @@ -329,7 +349,7 @@ _generate_varstore_inner_maps (const hb_set_t& varidx_set, { if (varidx_set.is_empty () || subtable_count == 0) return; - inner_maps.resize (subtable_count); + if (unlikely (!inner_maps.resize (subtable_count))) return; for (unsigned idx : varidx_set) { uint16_t major = idx >> 16; @@ -356,7 +376,7 @@ _get_hb_font_with_variations (const hb_subset_plan_t *plan) { hb_variation_t var; var.tag = _.first; - var.value = _.second; + var.value = _.second.middle; vars.push (var); } @@ -541,6 +561,8 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, unicodes->get_population () < cmap_unicodes->get_population () && glyphs->get_population () < cmap_unicodes->get_population ()) { + plan->codepoint_to_glyph->alloc (unicodes->get_population () + glyphs->get_population ()); + auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes; for (hb_codepoint_t gid : *glyphs) { @@ -569,6 +591,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, } else { + plan->codepoint_to_glyph->alloc (cmap_unicodes->get_population ()); for (hb_codepoint_t cp : *cmap_unicodes) { hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; @@ -581,9 +604,10 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, } /* Add gids which where requested, but not mapped in cmap */ + unsigned num_glyphs = plan->source->get_num_glyphs (); for (hb_codepoint_t gid : *glyphs) { - if (gid >= plan->source->get_num_glyphs ()) + if (gid >= num_glyphs) break; plan->_glyphset_gsub.add (gid); } @@ -616,7 +640,9 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count; if (unlikely (--operation_count < 0)) return operation_count; - for (auto &item : glyf.glyph_for_gid (gid).get_composite_iterator ()) + auto glyph = glyf.glyph_for_gid (gid); + + for (auto &item : glyph.get_composite_iterator ()) operation_count = _glyf_add_gid_and_children (glyf, item.get_gid (), @@ -625,7 +651,7 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, depth); #ifndef HB_NO_VAR_COMPOSITES - for (auto &item : glyf.glyph_for_gid (gid).get_var_composite_iterator ()) + for (auto &item : glyph.get_var_composite_iterator ()) { operation_count = _glyf_add_gid_and_children (glyf, @@ -648,7 +674,7 @@ _nameid_closure (hb_subset_plan_t* plan, #endif #ifndef HB_NO_VAR if (!plan->all_axes_pinned) - plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids); + plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->axes_old_index_tag_map, &plan->name_ids); #endif #ifndef HB_NO_COLOR if (!drop_tables->has (HB_OT_TAG_CPAL)) @@ -677,7 +703,11 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, { OT::glyf_accelerator_t glyf (plan->source); #ifndef HB_NO_SUBSET_CFF - OT::cff1::accelerator_t cff (plan->source); + // Note: we cannot use inprogress_accelerator here, since it has not been + // created yet. So in case of preprocessed-face (and otherwise), we do an + // extra sanitize pass here, which is not ideal. + OT::cff1::accelerator_subset_t stack_cff (plan->accelerator ? nullptr : plan->source); + const OT::cff1::accelerator_subset_t *cff (plan->accelerator ? plan->accelerator->cff1_accel.get () : &stack_cff); #endif plan->_glyphset_gsub.add (0); // Not-def @@ -694,7 +724,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, &plan->gsub_features, &plan->gsub_langsys, &plan->gsub_feature_record_cond_idx_map, - &plan->gsub_feature_substitutes_map); + &plan->gsub_feature_substitutes_map, + plan->gsub_insert_catch_all_feature_variation_rec); if (!drop_tables->has (HB_OT_TAG_GPOS)) _closure_glyphs_lookups_features<GPOS> ( @@ -704,7 +735,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, &plan->gpos_features, &plan->gpos_langsys, &plan->gpos_feature_record_cond_idx_map, - &plan->gpos_feature_substitutes_map); + &plan->gpos_feature_substitutes_map, + plan->gpos_insert_catch_all_feature_variation_rec); #endif _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ()); @@ -737,9 +769,9 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, if (!plan->accelerator || plan->accelerator->has_seac) { bool has_seac = false; - if (cff.is_valid ()) + if (cff->is_valid ()) for (hb_codepoint_t gid : cur_glyphset) - if (_add_cff_seac_components (cff, gid, &plan->_glyphset)) + if (_add_cff_seac_components (*cff, gid, &plan->_glyphset)) has_seac = true; plan->has_seac = has_seac; } @@ -747,7 +779,6 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _remove_invalid_gids (&plan->_glyphset, plan->source->get_num_glyphs ()); - #ifndef HB_NO_VAR if (!drop_tables->has (HB_OT_TAG_GDEF)) _collect_layout_variation_indices (plan); @@ -759,10 +790,10 @@ _create_glyph_map_gsub (const hb_set_t* glyph_set_gsub, const hb_map_t* glyph_map, hb_map_t* out) { + out->alloc (glyph_set_gsub->get_population ()); + hb_iter (glyph_set_gsub) | hb_map ([&] (hb_codepoint_t gid) { - return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, - glyph_map->get (gid)); + return hb_codepoint_pair_t (gid, glyph_map->get (gid)); }) | hb_sink (out) ; @@ -775,11 +806,13 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, const hb_map_t *requested_glyph_map, hb_map_t *glyph_map, /* OUT */ hb_map_t *reverse_glyph_map, /* OUT */ + hb_sorted_vector_t<hb_codepoint_pair_t> *new_to_old_gid_list /* OUT */, unsigned int *num_glyphs /* OUT */) { unsigned pop = all_gids_to_retain->get_population (); - reverse_glyph_map->resize (pop); - glyph_map->resize (pop); + reverse_glyph_map->alloc (pop); + glyph_map->alloc (pop); + new_to_old_gid_list->alloc (pop); if (*requested_glyph_map) { @@ -803,45 +836,44 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, for (auto old_gid : all_gids_to_retain->iter ()) { if (old_gid == 0) { - reverse_glyph_map->set(0, 0); + new_to_old_gid_list->push (hb_pair<hb_codepoint_t, hb_codepoint_t> (0u, 0u)); continue; } hb_codepoint_t* new_gid; if (!requested_glyph_map->has (old_gid, &new_gid)) { - remaining.add(old_gid); + remaining.add(old_gid); continue; } if (*new_gid > max_glyph) max_glyph = *new_gid; - reverse_glyph_map->set (*new_gid, old_gid); + new_to_old_gid_list->push (hb_pair (*new_gid, old_gid)); } + new_to_old_gid_list->qsort (); // Anything that wasn't mapped by the requested mapping should // be placed after the requested mapping. for (auto old_gid : remaining) - { - reverse_glyph_map->set(++max_glyph, old_gid); - } + new_to_old_gid_list->push (hb_pair (++max_glyph, old_gid)); *num_glyphs = max_glyph + 1; } else if (!retain_gids) { + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0) - | hb_sink (reverse_glyph_map) + | hb_sink (new_to_old_gid_list) ; - *num_glyphs = reverse_glyph_map->get_population (); + *num_glyphs = new_to_old_gid_list->length; } else { + hb_iter (all_gids_to_retain) | hb_map ([] (hb_codepoint_t _) { - return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, _); + return hb_codepoint_pair_t (_, _); }) - | hb_sink (reverse_glyph_map) + | hb_sink (new_to_old_gid_list) ; hb_codepoint_t max_glyph = HB_SET_VALUE_INVALID; @@ -850,8 +882,11 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, *num_glyphs = max_glyph + 1; } - + reverse_glyph_map->iter () - | hb_map (&hb_pair_t<hb_codepoint_t, hb_codepoint_t>::reverse) + + hb_iter (new_to_old_gid_list) + | hb_sink (reverse_glyph_map) + ; + + hb_iter (new_to_old_gid_list) + | hb_map (&hb_codepoint_pair_t::reverse) | hb_sink (glyph_map) ; @@ -884,24 +919,35 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) hb_tag_t axis_tag = axis.get_axis_tag (); plan->axes_old_index_tag_map.set (old_axis_idx, axis_tag); - if (!plan->user_axes_location.has (axis_tag)) + if (!plan->user_axes_location.has (axis_tag) || + !plan->user_axes_location.get (axis_tag).is_point ()) { axis_not_pinned = true; plan->axes_index_map.set (old_axis_idx, new_axis_idx); new_axis_idx++; } - else + + if (plan->user_axes_location.has (axis_tag)) { - int normalized_v = axis.normalize_axis_value (plan->user_axes_location.get (axis_tag)); + Triple axis_range = plan->user_axes_location.get (axis_tag); + int normalized_min = axis.normalize_axis_value (axis_range.minimum); + int normalized_default = axis.normalize_axis_value (axis_range.middle); + int normalized_max = axis.normalize_axis_value (axis_range.maximum); + if (has_avar && old_axis_idx < avar_axis_count) { - normalized_v = seg_maps->map (normalized_v); + normalized_min = seg_maps->map (normalized_min); + normalized_default = seg_maps->map (normalized_default); + normalized_max = seg_maps->map (normalized_max); } - plan->axes_location.set (axis_tag, normalized_v); - if (normalized_v != 0) + plan->axes_location.set (axis_tag, Triple (static_cast<float> (normalized_min), + static_cast<float> (normalized_default), + static_cast<float> (normalized_max))); + + if (normalized_default != 0) plan->pinned_at_default = false; - plan->normalized_coords[old_axis_idx] = normalized_v; + plan->normalized_coords[old_axis_idx] = normalized_default; } old_axis_idx++; @@ -968,7 +1014,7 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) continue; } plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); - plan->bounds_width_map.set (new_gid, extents.width); + plan->bounds_width_vec[new_gid] = extents.width; } if (_vmtx.has_data ()) @@ -985,7 +1031,7 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) continue; } plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); - plan->bounds_height_map.set (new_gid, extents.height); + plan->bounds_height_vec[new_gid] = extents.height; } } hb_font_destroy (font); @@ -1018,6 +1064,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, glyph_map = hb_map_create (); reverse_glyph_map = hb_map_create (); + gsub_insert_catch_all_feature_variation_rec = false; + gpos_insert_catch_all_feature_variation_rec = false; gdef_varstore_inner_maps.init (); user_axes_location = input->axes_location; @@ -1065,6 +1113,7 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, &input->glyph_map, glyph_map, reverse_glyph_map, + &new_to_old_gid_list, &_num_output_glyphs))) { return; } @@ -1082,6 +1131,13 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second); } + bounds_width_vec.resize (_num_output_glyphs, false); + for (auto &v : bounds_width_vec) + v = 0xFFFFFFFF; + bounds_height_vec.resize (_num_output_glyphs, false); + for (auto &v : bounds_height_vec) + v = 0xFFFFFFFF; + if (unlikely (in_error ())) return; @@ -1091,19 +1147,9 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, if (attach_accelerator_data) { - hb_multimap_t gid_to_unicodes; - - hb_map_t &unicode_to_gid = *codepoint_to_glyph; - - for (auto unicode : unicodes) - { - auto gid = unicode_to_gid[unicode]; - gid_to_unicodes.add (gid, unicode); - } - inprogress_accelerator = - hb_subset_accelerator_t::create (*codepoint_to_glyph, - gid_to_unicodes, + hb_subset_accelerator_t::create (source, + *codepoint_to_glyph, unicodes, has_seac); @@ -1115,6 +1161,29 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, #undef HB_SUBSET_PLAN_MEMBER } +hb_subset_plan_t::~hb_subset_plan_t() +{ + hb_face_destroy (dest); + + hb_map_destroy (codepoint_to_glyph); + hb_map_destroy (glyph_map); + hb_map_destroy (reverse_glyph_map); +#ifndef HB_NO_SUBSET_CFF + cff1_accel.fini (); + cff2_accel.fini (); +#endif + hb_face_destroy (source); + +#ifdef HB_EXPERIMENTAL_API + for (auto _ : name_table_overrides.iter_ref ()) + _.second.fini (); +#endif + + if (inprogress_accelerator) + hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator); +} + + /** * hb_subset_plan_create_or_fail: * @face: font face to create the plan for. diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index 19470ff83e..d156de05d7 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -67,28 +67,17 @@ struct head_maxp_info_t typedef struct head_maxp_info_t head_maxp_info_t; +namespace OT { + struct cff1_subset_accelerator_t; + struct cff2_subset_accelerator_t; +} + struct hb_subset_plan_t { HB_INTERNAL hb_subset_plan_t (hb_face_t *, const hb_subset_input_t *input); - ~hb_subset_plan_t() - { - hb_face_destroy (source); - hb_face_destroy (dest); - - hb_map_destroy (codepoint_to_glyph); - hb_map_destroy (glyph_map); - hb_map_destroy (reverse_glyph_map); - -#ifdef HB_EXPERIMENTAL_API - for (auto _ : name_table_overrides) - _.second.fini (); -#endif - - if (inprogress_accelerator) - hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator); - } + HB_INTERNAL ~hb_subset_plan_t(); hb_object_header_t header; @@ -106,6 +95,12 @@ struct hb_subset_plan_t // Plan is only good for a specific source/dest so keep them with it hb_face_t *source; +#ifndef HB_NO_SUBSET_CFF + // These have to be immediately after source: + hb_face_lazy_loader_t<OT::cff1_subset_accelerator_t, 1> cff1_accel; + hb_face_lazy_loader_t<OT::cff2_subset_accelerator_t, 2> cff2_accel; +#endif + hb_face_t *dest; unsigned int _num_output_glyphs; @@ -114,6 +109,10 @@ struct hb_subset_plan_t bool pinned_at_default; bool has_seac; + // whether to insert a catch-all FeatureVariationRecord + bool gsub_insert_catch_all_feature_variation_rec; + bool gpos_insert_catch_all_feature_variation_rec; + #define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name; #include "hb-subset-plan-member-list.hh" #undef HB_SUBSET_PLAN_MEMBER @@ -127,25 +126,31 @@ struct hb_subset_plan_t public: template<typename T> - hb_blob_ptr_t<T> source_table() + struct source_table_loader { - hb_lock_t lock (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr); + hb_blob_ptr_t<T> operator () (hb_subset_plan_t *plan) + { + hb_lock_t lock (plan->accelerator ? &plan->accelerator->sanitized_table_cache_lock : nullptr); - auto *cache = accelerator ? &accelerator->sanitized_table_cache : &sanitized_table_cache; - if (cache - && !cache->in_error () - && cache->has (+T::tableTag)) { - return hb_blob_reference (cache->get (+T::tableTag).get ()); - } + auto *cache = plan->accelerator ? &plan->accelerator->sanitized_table_cache : &plan->sanitized_table_cache; + if (cache + && !cache->in_error () + && cache->has (+T::tableTag)) { + return hb_blob_reference (cache->get (+T::tableTag).get ()); + } - hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (source)}; - hb_blob_t* ret = hb_blob_reference (table_blob.get ()); + hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (plan->source)}; + hb_blob_t* ret = hb_blob_reference (table_blob.get ()); - if (likely (cache)) - cache->set (+T::tableTag, std::move (table_blob)); + if (likely (cache)) + cache->set (+T::tableTag, std::move (table_blob)); - return ret; - } + return ret; + } + }; + + template<typename T> + auto source_table() HB_AUTO_RETURN (source_table_loader<T> {} (this)) bool in_error () const { return !successful; } @@ -184,15 +189,6 @@ struct hb_subset_plan_t return _num_output_glyphs; } - /* - * Given an output gid , returns true if that glyph id is an empty - * glyph (ie. it's a gid that we are dropping all data for). - */ - inline bool is_empty_glyph (hb_codepoint_t gid) const - { - return !_glyphset.has (gid); - } - inline bool new_gid_for_codepoint (hb_codepoint_t codepoint, hb_codepoint_t *new_gid) const { @@ -242,4 +238,5 @@ struct hb_subset_plan_t } }; + #endif /* HB_SUBSET_PLAN_HH */ diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 9c066e6d78..8e8a5eb0bd 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -62,6 +62,27 @@ using OT::Layout::GSUB; using OT::Layout::GPOS; + +#ifndef HB_NO_SUBSET_CFF +template<> +struct hb_subset_plan_t::source_table_loader<const OT::cff1> +{ + auto operator () (hb_subset_plan_t *plan) + HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel : + plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel : + plan->cff1_accel) +}; +template<> +struct hb_subset_plan_t::source_table_loader<const OT::cff2> +{ + auto operator () (hb_subset_plan_t *plan) + HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel : + plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel : + plan->cff2_accel) +}; +#endif + + /** * SECTION:hb-subset * @title: hb-subset @@ -192,15 +213,36 @@ _get_table_tags (const hb_subset_plan_t* plan, static unsigned _plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned table_len, - bool same_size) + hb_tag_t table_tag) { unsigned src_glyphs = plan->source->get_num_glyphs (); unsigned dst_glyphs = plan->glyphset ()->get_population (); + unsigned bulk = 8192; + /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's + * because those are expensive to subset, so giving them more room is fine. */ + bool same_size = table_tag == HB_OT_TAG_GSUB || + table_tag == HB_OT_TAG_GPOS || + table_tag == HB_OT_TAG_name; + + if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) + { + if (table_tag == HB_OT_TAG_CFF1) + { + /* Add some extra room for the CFF charset. */ + bulk += src_glyphs * 16; + } + else if (table_tag == HB_OT_TAG_CFF2) + { + /* Just extra CharString offsets. */ + bulk += src_glyphs * 4; + } + } + if (unlikely (!src_glyphs) || same_size) - return 512 + table_len; + return bulk + table_len; - return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); + return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); } /* @@ -262,45 +304,46 @@ _try_subset (const TableType *table, return _try_subset (table, buf, c); } +template <typename T> +static auto _do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ()) + +template <typename T> +static void _do_destroy (T &t, hb_priority<0>) {} + template<typename TableType> static bool _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf) { - hb_blob_ptr_t<TableType> source_blob = plan->source_table<TableType> (); - const TableType *table = source_blob.get (); + auto &&source_blob = plan->source_table<TableType> (); + auto *table = source_blob.get (); hb_tag_t tag = TableType::tableTag; - if (!source_blob.get_blob()->data) + hb_blob_t *blob = source_blob.get_blob(); + if (unlikely (!blob || !blob->data)) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - source_blob.destroy (); + _do_destroy (source_blob, hb_prioritize); return false; } - /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's - * because those are expensive to subset, so giving them more room is fine. */ - bool same_size_table = TableType::tableTag == HB_OT_TAG_GSUB || - TableType::tableTag == HB_OT_TAG_GPOS || - TableType::tableTag == HB_OT_TAG_name; - - unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob.get_length (), same_size_table); + unsigned buf_size = _plan_estimate_subset_table_size (plan, blob->length, TableType::tableTag); DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); if (unlikely (!buf.alloc (buf_size))) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); - source_blob.destroy (); + _do_destroy (source_blob, hb_prioritize); return false; } bool needed = false; hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); { - hb_subset_context_t c (source_blob.get_blob (), plan, &serializer, tag); + hb_subset_context_t c (blob, plan, &serializer, tag); needed = _try_subset (table, &buf, &c); } - source_blob.destroy (); + _do_destroy (source_blob, hb_prioritize); if (serializer.in_error () && !serializer.only_offset_overflow ()) { @@ -587,46 +630,49 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) offset += num_tables; } - hb_vector_t<char> buf; - buf.alloc (4096 - 16); - - bool success = true; - while (!pending_subset_tags.is_empty ()) { - if (subsetted_tags.in_error () - || pending_subset_tags.in_error ()) { - success = false; - goto end; - } + // Grouping to deallocate buf before calling hb_face_reference (plan->dest). - bool made_changes = false; - for (hb_tag_t tag : pending_subset_tags) + hb_vector_t<char> buf; + buf.alloc (8192 - 16); + + while (!pending_subset_tags.is_empty ()) { - if (!_dependencies_satisfied (plan, tag, - subsetted_tags, - pending_subset_tags)) - { - // delayed subsetting for some tables since they might have dependency on other tables - // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated - // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values - continue; + if (subsetted_tags.in_error () + || pending_subset_tags.in_error ()) { + success = false; + goto end; } - pending_subset_tags.del (tag); - subsetted_tags.add (tag); - made_changes = true; - - success = _subset_table (plan, buf, tag); - if (unlikely (!success)) goto end; - } + bool made_changes = false; + for (hb_tag_t tag : pending_subset_tags) + { + if (!_dependencies_satisfied (plan, tag, + subsetted_tags, + pending_subset_tags)) + { + // delayed subsetting for some tables since they might have dependency on other tables + // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated + // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values + continue; + } + + pending_subset_tags.del (tag); + subsetted_tags.add (tag); + made_changes = true; + + success = _subset_table (plan, buf, tag); + if (unlikely (!success)) goto end; + } - if (!made_changes) - { - DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed."); - success = false; - goto end; + if (!made_changes) + { + DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed."); + success = false; + goto end; + } } } diff --git a/thirdparty/harfbuzz/src/hb-subset.h b/thirdparty/harfbuzz/src/hb-subset.h index 6368ff93f0..93f1f7f10c 100644 --- a/thirdparty/harfbuzz/src/hb-subset.h +++ b/thirdparty/harfbuzz/src/hb-subset.h @@ -177,6 +177,13 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, #ifdef HB_EXPERIMENTAL_API HB_EXTERN hb_bool_t +hb_subset_input_set_axis_range (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag, + float axis_min_value, + float axis_max_value); + +HB_EXTERN hb_bool_t hb_subset_input_override_name_table (hb_subset_input_t *input, hb_ot_name_id_t name_id, unsigned platform_id, diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index d61ce48c01..23a96d7081 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -54,7 +54,7 @@ struct hb_vector_t hb_vector_t (const Iterable &o) : hb_vector_t () { auto iter = hb_iter (o); - if (iter.is_random_access_iterator) + if (iter.is_random_access_iterator || iter.has_fast_len) alloc (hb_len (iter), true); hb_copy (iter, *this); } @@ -62,7 +62,19 @@ struct hb_vector_t { alloc (o.length, true); if (unlikely (in_error ())) return; - copy_vector (o); + copy_array (o.as_array ()); + } + hb_vector_t (array_t o) : hb_vector_t () + { + alloc (o.length, true); + if (unlikely (in_error ())) return; + copy_array (o); + } + hb_vector_t (c_array_t o) : hb_vector_t () + { + alloc (o.length, true); + if (unlikely (in_error ())) return; + copy_array (o); } hb_vector_t (hb_vector_t &&o) { @@ -74,7 +86,7 @@ struct hb_vector_t ~hb_vector_t () { fini (); } public: - int allocated = 0; /* == -1 means allocation failed. */ + int allocated = 0; /* < 0 means allocation failed. */ unsigned int length = 0; public: Type *arrayZ = nullptr; @@ -90,19 +102,21 @@ struct hb_vector_t void fini () { - shrink_vector (0); - hb_free (arrayZ); + /* We allow a hack to make the vector point to a foriegn array + * by the user. In that case length/arrayZ are non-zero but + * allocated is zero. Don't free anything. */ + if (allocated) + { + shrink_vector (0); + hb_free (arrayZ); + } init (); } void reset () { if (unlikely (in_error ())) - /* Big Hack! We don't know the true allocated size before - * an allocation failure happened. But we know it was at - * least as big as length. Restore it to that and continue - * as if error did not happen. */ - allocated = length; + reset_error (); resize (0); } @@ -119,7 +133,7 @@ struct hb_vector_t alloc (o.length, true); if (unlikely (in_error ())) return *this; - copy_vector (o); + copy_array (o.as_array ()); return *this; } @@ -191,7 +205,7 @@ struct hb_vector_t Type *push () { if (unlikely (!resize (length + 1))) - return &Crap (Type); + return std::addressof (Crap (Type)); return std::addressof (arrayZ[length - 1]); } template <typename T, @@ -201,7 +215,7 @@ struct hb_vector_t Type *push (T&& v) { Type *p = push (); - if (p == &Crap (Type)) + if (p == std::addressof (Crap (Type))) // If push failed to allocate then don't copy v, since this may cause // the created copy to leak memory since we won't have stored a // reference to it. @@ -214,24 +228,33 @@ struct hb_vector_t hb_enable_if (std::is_copy_constructible<T2>::value)> Type *push (T&& v) { - if (unlikely (!alloc (length + 1))) + if (unlikely ((int) length >= allocated && !alloc (length + 1))) // If push failed to allocate then don't copy v, since this may cause // the created copy to leak memory since we won't have stored a // reference to it. - return &Crap (Type); + return std::addressof (Crap (Type)); /* Emplace. */ - length++; - Type *p = std::addressof (arrayZ[length - 1]); + Type *p = std::addressof (arrayZ[length++]); return new (p) Type (std::forward<T> (v)); } bool in_error () const { return allocated < 0; } + void set_error () + { + assert (allocated >= 0); + allocated = -allocated - 1; + } + void reset_error () + { + assert (allocated < 0); + allocated = -(allocated + 1); + } template <typename T = Type, hb_enable_if (hb_is_trivially_copy_assignable(T))> Type * - realloc_vector (unsigned new_allocated) + realloc_vector (unsigned new_allocated, hb_priority<0>) { if (!new_allocated) { @@ -243,7 +266,7 @@ struct hb_vector_t template <typename T = Type, hb_enable_if (!hb_is_trivially_copy_assignable(T))> Type * - realloc_vector (unsigned new_allocated) + realloc_vector (unsigned new_allocated, hb_priority<0>) { if (!new_allocated) { @@ -263,31 +286,52 @@ struct hb_vector_t } return new_array; } + /* Specialization for hb_vector_t<hb_{vector,array}_t<U>> to speed up. */ + template <typename T = Type, + hb_enable_if (hb_is_same (T, hb_vector_t<typename T::item_t>) || + hb_is_same (T, hb_array_t <typename T::item_t>))> + Type * + realloc_vector (unsigned new_allocated, hb_priority<1>) + { + if (!new_allocated) + { + hb_free (arrayZ); + return nullptr; + } + return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); + } template <typename T = Type, hb_enable_if (hb_is_trivially_constructible(T))> void - grow_vector (unsigned size) + grow_vector (unsigned size, hb_priority<0>) { - memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ)); + hb_memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ)); length = size; } template <typename T = Type, hb_enable_if (!hb_is_trivially_constructible(T))> void - grow_vector (unsigned size) + grow_vector (unsigned size, hb_priority<0>) { - while (length < size) - { - length++; - new (std::addressof (arrayZ[length - 1])) Type (); - } + for (; length < size; length++) + new (std::addressof (arrayZ[length])) Type (); + } + /* Specialization for hb_vector_t<hb_{vector,array}_t<U>> to speed up. */ + template <typename T = Type, + hb_enable_if (hb_is_same (T, hb_vector_t<typename T::item_t>) || + hb_is_same (T, hb_array_t <typename T::item_t>))> + void + grow_vector (unsigned size, hb_priority<1>) + { + hb_memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ)); + length = size; } template <typename T = Type, hb_enable_if (hb_is_trivially_copyable (T))> void - copy_vector (const hb_vector_t &other) + copy_array (hb_array_t<const Type> other) { length = other.length; if (!HB_OPTIMIZE_SIZE_VAL && sizeof (T) >= sizeof (long long)) @@ -301,7 +345,7 @@ struct hb_vector_t hb_enable_if (!hb_is_trivially_copyable (T) && std::is_copy_constructible<T>::value)> void - copy_vector (const hb_vector_t &other) + copy_array (hb_array_t<const Type> other) { length = 0; while (length < other.length) @@ -316,7 +360,7 @@ struct hb_vector_t std::is_default_constructible<T>::value && std::is_copy_assignable<T>::value)> void - copy_vector (const hb_vector_t &other) + copy_array (hb_array_t<const Type> other) { length = 0; while (length < other.length) @@ -330,11 +374,15 @@ struct hb_vector_t void shrink_vector (unsigned size) { - while ((unsigned) length > size) + assert (size <= length); + if (!std::is_trivially_destructible<Type>::value) { - arrayZ[(unsigned) length - 1].~Type (); - length--; + unsigned count = length - size; + Type *p = arrayZ + length - 1; + while (count--) + p--->~Type (); } + length = size; } void @@ -381,18 +429,18 @@ struct hb_vector_t if (unlikely (overflows)) { - allocated = -1; + set_error (); return false; } - Type *new_array = realloc_vector (new_allocated); + Type *new_array = realloc_vector (new_allocated, hb_prioritize); if (unlikely (new_allocated && !new_array)) { if (new_allocated <= (unsigned) allocated) return true; // shrinking failed; it's okay; happens in our fuzzer - allocated = -1; + set_error (); return false; } @@ -411,7 +459,7 @@ struct hb_vector_t if (size > length) { if (initialize) - grow_vector (size); + grow_vector (size, hb_prioritize); } else if (size < length) { diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index 08d1f55a35..9b27acf598 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -41,13 +41,13 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 7 +#define HB_VERSION_MAJOR 8 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 3 +#define HB_VERSION_MINOR 0 /** * HB_VERSION_MICRO: * @@ -60,7 +60,7 @@ HB_BEGIN_DECLS * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "7.3.0" +#define HB_VERSION_STRING "8.0.0" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/harfbuzz/src/hb.hh b/thirdparty/harfbuzz/src/hb.hh index 205f8cf196..49119b8f82 100644 --- a/thirdparty/harfbuzz/src/hb.hh +++ b/thirdparty/harfbuzz/src/hb.hh @@ -315,6 +315,14 @@ extern "C" void hb_free_impl(void *ptr); #define __restrict #endif +#ifndef HB_ALWAYS_INLINE +#if defined(_MSC_VER) +#define HB_ALWAYS_INLINE __forceinline +#else +#define HB_ALWAYS_INLINE __attribute__((always_inline)) inline +#endif +#endif + /* * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch diff --git a/thirdparty/icu4c/common/unicode/ures.h b/thirdparty/icu4c/common/unicode/ures.h index cc25b6e49c..babc01d426 100644 --- a/thirdparty/icu4c/common/unicode/ures.h +++ b/thirdparty/icu4c/common/unicode/ures.h @@ -25,6 +25,7 @@ #ifndef URES_H #define URES_H +#include "unicode/char16ptr.h" #include "unicode/utypes.h" #include "unicode/uloc.h" @@ -812,7 +813,7 @@ inline UnicodeString ures_getUnicodeString(const UResourceBundle *resB, UErrorCode* status) { UnicodeString result; int32_t len = 0; - const char16_t *r = ures_getString(resB, &len, status); + const char16_t *r = ConstChar16Ptr(ures_getString(resB, &len, status)); if(U_SUCCESS(*status)) { result.setTo(true, r, len); } else { @@ -837,7 +838,7 @@ inline UnicodeString ures_getNextUnicodeString(UResourceBundle *resB, const char ** key, UErrorCode* status) { UnicodeString result; int32_t len = 0; - const char16_t* r = ures_getNextString(resB, &len, key, status); + const char16_t* r = ConstChar16Ptr(ures_getNextString(resB, &len, key, status)); if(U_SUCCESS(*status)) { result.setTo(true, r, len); } else { @@ -859,7 +860,7 @@ inline UnicodeString ures_getUnicodeStringByIndex(const UResourceBundle *resB, int32_t indexS, UErrorCode* status) { UnicodeString result; int32_t len = 0; - const char16_t* r = ures_getStringByIndex(resB, indexS, &len, status); + const char16_t* r = ConstChar16Ptr(ures_getStringByIndex(resB, indexS, &len, status)); if(U_SUCCESS(*status)) { result.setTo(true, r, len); } else { @@ -882,7 +883,7 @@ inline UnicodeString ures_getUnicodeStringByKey(const UResourceBundle *resB, const char* key, UErrorCode* status) { UnicodeString result; int32_t len = 0; - const char16_t* r = ures_getStringByKey(resB, key, &len, status); + const char16_t* r = ConstChar16Ptr(ures_getStringByKey(resB, key, &len, status)); if(U_SUCCESS(*status)) { result.setTo(true, r, len); } else { diff --git a/thirdparty/icu4c/common/unicode/uvernum.h b/thirdparty/icu4c/common/unicode/uvernum.h index f0fc671b4b..fc784b2492 100644 --- a/thirdparty/icu4c/common/unicode/uvernum.h +++ b/thirdparty/icu4c/common/unicode/uvernum.h @@ -59,7 +59,7 @@ * This value will change in the subsequent releases of ICU * @stable ICU 2.6 */ -#define U_ICU_VERSION_MINOR_NUM 1 +#define U_ICU_VERSION_MINOR_NUM 2 /** The current ICU patchlevel version as an integer. * This value will change in the subsequent releases of ICU @@ -132,7 +132,7 @@ * This value will change in the subsequent releases of ICU * @stable ICU 2.4 */ -#define U_ICU_VERSION "73.1" +#define U_ICU_VERSION "73.2" /** * The current ICU library major version number as a string, for library name suffixes. @@ -151,7 +151,7 @@ /** Data version in ICU4C. * @internal ICU 4.4 Internal Use Only **/ -#define U_ICU_DATA_VERSION "73.1" +#define U_ICU_DATA_VERSION "73.2" #endif /* U_HIDE_INTERNAL_API */ /*=========================================================================== diff --git a/thirdparty/icu4c/icudt73l.dat b/thirdparty/icu4c/icudt73l.dat Binary files differindex b8e2cf7567..fc007e5f96 100644 --- a/thirdparty/icu4c/icudt73l.dat +++ b/thirdparty/icu4c/icudt73l.dat diff --git a/thirdparty/minizip/patches/empty-zip-fix.patch b/thirdparty/minizip/patches/empty-zip-fix.patch new file mode 100644 index 0000000000..7885d4c3a3 --- /dev/null +++ b/thirdparty/minizip/patches/empty-zip-fix.patch @@ -0,0 +1,193 @@ +diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c +index e83aff2773..af73f06137 100644 +--- a/thirdparty/minizip/unzip.c ++++ b/thirdparty/minizip/unzip.c +@@ -408,6 +408,12 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + #define BUFREADCOMMENT (0x400) + #endif + ++/* GODOT start */ ++#ifndef CENTRALDIRINVALID ++#define CENTRALDIRINVALID (0xffffffffffffffff) ++#endif ++/* GODOT end */ ++ + /* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +@@ -419,10 +425,14 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ +- ZPOS64_T uPosFound=0; ++ /* GODOT start */ ++ ZPOS64_T uPosFound=CENTRALDIRINVALID; ++ /* GODOT end */ + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); +@@ -432,7 +442,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + uBackRead = 4; + while (uBackRead<uMaxBack) +@@ -462,7 +474,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f + break; + } + +- if (uPosFound!=0) ++ /* GODOT start */ ++ if (uPosFound!=CENTRALDIRINVALID) ++ /* GODOT end */ + break; + } + TRYFREE(buf); +@@ -485,12 +499,16 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ +- ZPOS64_T uPosFound=0; ++ /* GODOT start */ ++ ZPOS64_T uPosFound=CENTRALDIRINVALID; ++ /* GODOT end */ + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); +@@ -500,7 +518,9 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + uBackRead = 4; + while (uBackRead<uMaxBack) +@@ -530,47 +550,71 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib + break; + } + +- if (uPosFound!=0) ++ /* GODOT start */ ++ if (uPosFound!=CENTRALDIRINVALID) ++ /* GODOT end */ + break; + } + TRYFREE(buf); +- if (uPosFound == 0) +- return 0; ++ /* GODOT start */ ++ if (uPosFound == CENTRALDIRINVALID) ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + if (uL != 0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + if (uL != 1) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + if (uL != 0x06064b50) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + return relativeOffset; + } +@@ -625,7 +669,9 @@ local unzFile unzOpenInternal (const void *path, + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); +- if (central_pos) ++ /* GODOT start */ ++ if (central_pos != CENTRALDIRINVALID) ++ /* GODOT end */ + { + uLong uS; + ZPOS64_T uL64; +@@ -687,7 +733,9 @@ local unzFile unzOpenInternal (const void *path, + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); +- if (central_pos==0) ++ /* GODOT start */ ++ if (central_pos==CENTRALDIRINVALID) ++ /* GODOT end */ + err=UNZ_ERRNO; + + us.isZip64 = 0; diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c index e83aff2773..f72bf3974f 100644 --- a/thirdparty/minizip/unzip.c +++ b/thirdparty/minizip/unzip.c @@ -408,6 +408,12 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, #define BUFREADCOMMENT (0x400) #endif +/* GODOT start */ +#ifndef CENTRALDIRINVALID +#define CENTRALDIRINVALID (0xffffffffffffffff) +#endif +/* GODOT end */ + /* Locate the Central directory of a zipfile (at the end, just before the global comment) @@ -419,10 +425,14 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + /* GODOT start */ + ZPOS64_T uPosFound=CENTRALDIRINVALID; + /* GODOT end */ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); @@ -432,7 +442,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ uBackRead = 4; while (uBackRead<uMaxBack) @@ -462,7 +474,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f break; } - if (uPosFound!=0) + /* GODOT start */ + if (uPosFound!=CENTRALDIRINVALID) + /* GODOT end */ break; } TRYFREE(buf); @@ -485,12 +499,16 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + /* GODOT start */ + ZPOS64_T uPosFound=CENTRALDIRINVALID; + /* GODOT end */ uLong uL; ZPOS64_T relativeOffset; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); @@ -500,7 +518,9 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ uBackRead = 4; while (uBackRead<uMaxBack) @@ -530,47 +550,71 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib break; } - if (uPosFound!=0) + /* GODOT start */ + if (uPosFound!=CENTRALDIRINVALID) + /* GODOT end */ break; } TRYFREE(buf); - if (uPosFound == 0) - return 0; + /* GODOT start */ + if (uPosFound == CENTRALDIRINVALID) + return CENTRALDIRINVALID; + /* GODOT end */ /* Zip64 end of central directory locator */ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* the signature, already checked */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* number of the disk with the start of the zip64 end of central directory */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ if (uL != 0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* relative offset of the zip64 end of central directory record */ if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* total number of disks */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ if (uL != 1) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* Goto end of central directory record */ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* the signature */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ if (uL != 0x06064b50) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ return relativeOffset; } @@ -625,7 +669,9 @@ local unzFile unzOpenInternal (const void *path, return NULL; central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); - if (central_pos) + /* GODOT start */ + if (central_pos != CENTRALDIRINVALID) + /* GODOT end */ { uLong uS; ZPOS64_T uL64; @@ -687,7 +733,9 @@ local unzFile unzOpenInternal (const void *path, else { central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) + /* GODOT start */ + if (central_pos==CENTRALDIRINVALID) + /* GODOT end */ err=UNZ_ERRNO; us.isZip64 = 0; diff --git a/thirdparty/openxr/COPYING.adoc b/thirdparty/openxr/COPYING.adoc index 3a31362acb..473e7fdc5d 100644 --- a/thirdparty/openxr/COPYING.adoc +++ b/thirdparty/openxr/COPYING.adoc @@ -1,6 +1,6 @@ = COPYING.adoc for the Khronos Group OpenXR projects -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // // SPDX-License-Identifier: CC-BY-4.0 diff --git a/thirdparty/openxr/include/openxr/openxr.h b/thirdparty/openxr/include/openxr/openxr.h index 3663f9f14d..5d953fb9ba 100644 --- a/thirdparty/openxr/include/openxr/openxr.h +++ b/thirdparty/openxr/include/openxr/openxr.h @@ -2,7 +2,7 @@ #define OPENXR_H_ 1 /* -** Copyright 2017-2022 The Khronos Group Inc. +** Copyright 2017-2023 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -25,7 +25,7 @@ extern "C" { ((((major) & 0xffffULL) << 48) | (((minor) & 0xffffULL) << 32) | ((patch) & 0xffffffffULL)) // OpenXR current version number. -#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 26) +#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 28) #define XR_VERSION_MAJOR(version) (uint16_t)(((uint64_t)(version) >> 48)& 0xffffULL) #define XR_VERSION_MINOR(version) (uint16_t)(((uint64_t)(version) >> 32) & 0xffffULL) @@ -74,6 +74,12 @@ extern "C" { #define XR_MAX_EVENT_DATA_SIZE sizeof(XrEventDataBuffer) +#define XR_EXTENSION_ENUM_BASE 1000000000 + + +#define XR_EXTENSION_ENUM_STRIDE 1000 + + #if !defined(XR_MAY_ALIAS) #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4)) #define XR_MAY_ALIAS __attribute__((__may_alias__)) @@ -214,6 +220,15 @@ typedef enum XrResult { XR_ERROR_MARKER_ID_INVALID_VARJO = -1000124001, XR_ERROR_SPATIAL_ANCHOR_NAME_NOT_FOUND_MSFT = -1000142001, XR_ERROR_SPATIAL_ANCHOR_NAME_INVALID_MSFT = -1000142002, + XR_ERROR_SPACE_MAPPING_INSUFFICIENT_FB = -1000169000, + XR_ERROR_SPACE_LOCALIZATION_FAILED_FB = -1000169001, + XR_ERROR_SPACE_NETWORK_TIMEOUT_FB = -1000169002, + XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB = -1000169003, + XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB = -1000169004, + XR_ERROR_PASSTHROUGH_COLOR_LUT_BUFFER_SIZE_MISMATCH_META = -1000266000, + XR_ERROR_HINT_ALREADY_SET_QCOM = -1000306000, + XR_ERROR_SPACE_NOT_LOCATABLE_EXT = -1000429000, + XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT = -1000429001, XR_RESULT_MAX_ENUM = 0x7FFFFFFF } XrResult; @@ -341,6 +356,11 @@ typedef enum XrStructureType { XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT = 1000066001, XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB = 1000070000, XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB = 1000072000, + XR_TYPE_BODY_TRACKER_CREATE_INFO_FB = 1000076001, + XR_TYPE_BODY_JOINTS_LOCATE_INFO_FB = 1000076002, + XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_FB = 1000076004, + XR_TYPE_BODY_JOINT_LOCATIONS_FB = 1000076005, + XR_TYPE_BODY_SKELETON_FB = 1000076006, XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT = 1000078000, XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE = 1000079000, XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT = 1000080000, @@ -421,6 +441,9 @@ typedef enum XrStructureType { XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO = 1000124000, XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO = 1000124001, XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO = 1000124002, + XR_TYPE_FRAME_END_INFO_ML = 1000135000, + XR_TYPE_GLOBAL_DIMMER_FRAME_END_INFO_ML = 1000136000, + XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML = 1000137000, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT = 1000142000, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT = 1000142001, XR_TYPE_SPACE_QUERY_INFO_FB = 1000156001, @@ -438,19 +461,64 @@ typedef enum XrStructureType { XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB = 1000161000, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB = 1000162000, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB = 1000163000, + XR_TYPE_SPACE_SHARE_INFO_FB = 1000169001, + XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB = 1000169002, XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB = 1000171000, XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB = 1000171001, + XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB = 1000173001, XR_TYPE_SEMANTIC_LABELS_FB = 1000175000, XR_TYPE_ROOM_LAYOUT_FB = 1000175001, XR_TYPE_BOUNDARY_2D_FB = 1000175002, + XR_TYPE_SEMANTIC_LABELS_SUPPORT_INFO_FB = 1000175010, XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE = 1000196000, + XR_TYPE_EVENT_DATA_SCENE_CAPTURE_COMPLETE_FB = 1000198001, + XR_TYPE_SCENE_CAPTURE_REQUEST_INFO_FB = 1000198050, XR_TYPE_SPACE_CONTAINER_FB = 1000199000, + XR_TYPE_FOVEATION_EYE_TRACKED_PROFILE_CREATE_INFO_META = 1000200000, + XR_TYPE_FOVEATION_EYE_TRACKED_STATE_META = 1000200001, + XR_TYPE_SYSTEM_FOVEATION_EYE_TRACKED_PROPERTIES_META = 1000200002, + XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_FB = 1000201004, + XR_TYPE_FACE_TRACKER_CREATE_INFO_FB = 1000201005, + XR_TYPE_FACE_EXPRESSION_INFO_FB = 1000201002, + XR_TYPE_FACE_EXPRESSION_WEIGHTS_FB = 1000201006, + XR_TYPE_EYE_TRACKER_CREATE_INFO_FB = 1000202001, + XR_TYPE_EYE_GAZES_INFO_FB = 1000202002, + XR_TYPE_EYE_GAZES_FB = 1000202003, + XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_FB = 1000202004, XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB = 1000203002, XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB = 1000204000, + XR_TYPE_HAPTIC_PCM_VIBRATION_FB = 1000209001, + XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB = 1000209002, + XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_FB = 1000212000, + XR_TYPE_LOCAL_DIMMING_FRAME_END_INFO_META = 1000216000, + XR_TYPE_SYSTEM_VIRTUAL_KEYBOARD_PROPERTIES_META = 1000219001, + XR_TYPE_VIRTUAL_KEYBOARD_CREATE_INFO_META = 1000219002, + XR_TYPE_VIRTUAL_KEYBOARD_SPACE_CREATE_INFO_META = 1000219003, + XR_TYPE_VIRTUAL_KEYBOARD_LOCATION_INFO_META = 1000219004, + XR_TYPE_VIRTUAL_KEYBOARD_MODEL_VISIBILITY_SET_INFO_META = 1000219005, + XR_TYPE_VIRTUAL_KEYBOARD_ANIMATION_STATE_META = 1000219006, + XR_TYPE_VIRTUAL_KEYBOARD_MODEL_ANIMATION_STATES_META = 1000219007, + XR_TYPE_VIRTUAL_KEYBOARD_TEXTURE_DATA_META = 1000219009, + XR_TYPE_VIRTUAL_KEYBOARD_INPUT_INFO_META = 1000219010, + XR_TYPE_VIRTUAL_KEYBOARD_TEXT_CONTEXT_CHANGE_INFO_META = 1000219011, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_COMMIT_TEXT_META = 1000219014, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_BACKSPACE_META = 1000219015, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_ENTER_META = 1000219016, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_SHOWN_META = 1000219017, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_HIDDEN_META = 1000219018, + XR_TYPE_EXTERNAL_CAMERA_OCULUS = 1000226000, XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META = 1000227000, XR_TYPE_PERFORMANCE_METRICS_STATE_META = 1000232001, XR_TYPE_PERFORMANCE_METRICS_COUNTER_META = 1000232002, + XR_TYPE_SPACE_LIST_SAVE_INFO_FB = 1000238000, + XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB = 1000238001, + XR_TYPE_SPACE_USER_CREATE_INFO_FB = 1000241001, XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META = 1000245000, + XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META = 1000266000, + XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META = 1000266001, + XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META = 1000266002, + XR_TYPE_PASSTHROUGH_COLOR_MAP_LUT_META = 1000266100, + XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META = 1000266101, XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC = 1000317001, XR_TYPE_PASSTHROUGH_COLOR_HTC = 1000317002, XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC = 1000317003, @@ -459,9 +527,21 @@ typedef enum XrStructureType { XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC = 1000318001, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC = 1000318002, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT = 1000373000, + XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX = 1000375000, + XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX = 1000375001, + XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT = 1000428000, + XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT = 1000428001, + XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT = 1000429001, + XR_TYPE_PLANE_DETECTOR_BEGIN_INFO_EXT = 1000429002, + XR_TYPE_PLANE_DETECTOR_GET_INFO_EXT = 1000429003, + XR_TYPE_PLANE_DETECTOR_LOCATIONS_EXT = 1000429004, + XR_TYPE_PLANE_DETECTOR_LOCATION_EXT = 1000429005, + XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT = 1000429006, + XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT = 1000429007, XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR, + XR_TYPE_DEVICE_PCM_SAMPLE_RATE_GET_INFO_FB = XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB, XR_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } XrStructureType; @@ -492,6 +572,7 @@ typedef enum XrReferenceSpaceType { XR_REFERENCE_SPACE_TYPE_STAGE = 3, XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT = 1000038000, XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO = 1000121000, + XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT = 1000426000, XR_REFERENCE_SPACE_TYPE_MAX_ENUM = 0x7FFFFFFF } XrReferenceSpaceType; @@ -536,6 +617,7 @@ typedef enum XrObjectType { XR_OBJECT_TYPE_SPATIAL_ANCHOR_MSFT = 1000039000, XR_OBJECT_TYPE_SPATIAL_GRAPH_NODE_BINDING_MSFT = 1000049000, XR_OBJECT_TYPE_HAND_TRACKER_EXT = 1000051000, + XR_OBJECT_TYPE_BODY_TRACKER_FB = 1000076000, XR_OBJECT_TYPE_SCENE_OBSERVER_MSFT = 1000097000, XR_OBJECT_TYPE_SCENE_MSFT = 1000097001, XR_OBJECT_TYPE_FACIAL_TRACKER_HTC = 1000104000, @@ -545,7 +627,13 @@ typedef enum XrObjectType { XR_OBJECT_TYPE_PASSTHROUGH_LAYER_FB = 1000118002, XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB = 1000118004, XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT = 1000142000, + XR_OBJECT_TYPE_FACE_TRACKER_FB = 1000201000, + XR_OBJECT_TYPE_EYE_TRACKER_FB = 1000202000, + XR_OBJECT_TYPE_VIRTUAL_KEYBOARD_META = 1000219000, + XR_OBJECT_TYPE_SPACE_USER_FB = 1000241000, + XR_OBJECT_TYPE_PASSTHROUGH_COLOR_LUT_META = 1000266000, XR_OBJECT_TYPE_PASSTHROUGH_HTC = 1000317000, + XR_OBJECT_TYPE_PLANE_DETECTOR_EXT = 1000429000, XR_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } XrObjectType; typedef XrFlags64 XrInstanceCreateFlags; @@ -2542,6 +2630,167 @@ typedef struct XrCompositionLayerSecureContentFB { +#define XR_FB_body_tracking 1 +XR_DEFINE_HANDLE(XrBodyTrackerFB) +#define XR_FB_body_tracking_SPEC_VERSION 1 +#define XR_FB_BODY_TRACKING_EXTENSION_NAME "XR_FB_body_tracking" + +typedef enum XrBodyJointFB { + XR_BODY_JOINT_ROOT_FB = 0, + XR_BODY_JOINT_HIPS_FB = 1, + XR_BODY_JOINT_SPINE_LOWER_FB = 2, + XR_BODY_JOINT_SPINE_MIDDLE_FB = 3, + XR_BODY_JOINT_SPINE_UPPER_FB = 4, + XR_BODY_JOINT_CHEST_FB = 5, + XR_BODY_JOINT_NECK_FB = 6, + XR_BODY_JOINT_HEAD_FB = 7, + XR_BODY_JOINT_LEFT_SHOULDER_FB = 8, + XR_BODY_JOINT_LEFT_SCAPULA_FB = 9, + XR_BODY_JOINT_LEFT_ARM_UPPER_FB = 10, + XR_BODY_JOINT_LEFT_ARM_LOWER_FB = 11, + XR_BODY_JOINT_LEFT_HAND_WRIST_TWIST_FB = 12, + XR_BODY_JOINT_RIGHT_SHOULDER_FB = 13, + XR_BODY_JOINT_RIGHT_SCAPULA_FB = 14, + XR_BODY_JOINT_RIGHT_ARM_UPPER_FB = 15, + XR_BODY_JOINT_RIGHT_ARM_LOWER_FB = 16, + XR_BODY_JOINT_RIGHT_HAND_WRIST_TWIST_FB = 17, + XR_BODY_JOINT_LEFT_HAND_PALM_FB = 18, + XR_BODY_JOINT_LEFT_HAND_WRIST_FB = 19, + XR_BODY_JOINT_LEFT_HAND_THUMB_METACARPAL_FB = 20, + XR_BODY_JOINT_LEFT_HAND_THUMB_PROXIMAL_FB = 21, + XR_BODY_JOINT_LEFT_HAND_THUMB_DISTAL_FB = 22, + XR_BODY_JOINT_LEFT_HAND_THUMB_TIP_FB = 23, + XR_BODY_JOINT_LEFT_HAND_INDEX_METACARPAL_FB = 24, + XR_BODY_JOINT_LEFT_HAND_INDEX_PROXIMAL_FB = 25, + XR_BODY_JOINT_LEFT_HAND_INDEX_INTERMEDIATE_FB = 26, + XR_BODY_JOINT_LEFT_HAND_INDEX_DISTAL_FB = 27, + XR_BODY_JOINT_LEFT_HAND_INDEX_TIP_FB = 28, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_METACARPAL_FB = 29, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_PROXIMAL_FB = 30, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_INTERMEDIATE_FB = 31, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_DISTAL_FB = 32, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_TIP_FB = 33, + XR_BODY_JOINT_LEFT_HAND_RING_METACARPAL_FB = 34, + XR_BODY_JOINT_LEFT_HAND_RING_PROXIMAL_FB = 35, + XR_BODY_JOINT_LEFT_HAND_RING_INTERMEDIATE_FB = 36, + XR_BODY_JOINT_LEFT_HAND_RING_DISTAL_FB = 37, + XR_BODY_JOINT_LEFT_HAND_RING_TIP_FB = 38, + XR_BODY_JOINT_LEFT_HAND_LITTLE_METACARPAL_FB = 39, + XR_BODY_JOINT_LEFT_HAND_LITTLE_PROXIMAL_FB = 40, + XR_BODY_JOINT_LEFT_HAND_LITTLE_INTERMEDIATE_FB = 41, + XR_BODY_JOINT_LEFT_HAND_LITTLE_DISTAL_FB = 42, + XR_BODY_JOINT_LEFT_HAND_LITTLE_TIP_FB = 43, + XR_BODY_JOINT_RIGHT_HAND_PALM_FB = 44, + XR_BODY_JOINT_RIGHT_HAND_WRIST_FB = 45, + XR_BODY_JOINT_RIGHT_HAND_THUMB_METACARPAL_FB = 46, + XR_BODY_JOINT_RIGHT_HAND_THUMB_PROXIMAL_FB = 47, + XR_BODY_JOINT_RIGHT_HAND_THUMB_DISTAL_FB = 48, + XR_BODY_JOINT_RIGHT_HAND_THUMB_TIP_FB = 49, + XR_BODY_JOINT_RIGHT_HAND_INDEX_METACARPAL_FB = 50, + XR_BODY_JOINT_RIGHT_HAND_INDEX_PROXIMAL_FB = 51, + XR_BODY_JOINT_RIGHT_HAND_INDEX_INTERMEDIATE_FB = 52, + XR_BODY_JOINT_RIGHT_HAND_INDEX_DISTAL_FB = 53, + XR_BODY_JOINT_RIGHT_HAND_INDEX_TIP_FB = 54, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_METACARPAL_FB = 55, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_PROXIMAL_FB = 56, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_INTERMEDIATE_FB = 57, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_DISTAL_FB = 58, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_TIP_FB = 59, + XR_BODY_JOINT_RIGHT_HAND_RING_METACARPAL_FB = 60, + XR_BODY_JOINT_RIGHT_HAND_RING_PROXIMAL_FB = 61, + XR_BODY_JOINT_RIGHT_HAND_RING_INTERMEDIATE_FB = 62, + XR_BODY_JOINT_RIGHT_HAND_RING_DISTAL_FB = 63, + XR_BODY_JOINT_RIGHT_HAND_RING_TIP_FB = 64, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_METACARPAL_FB = 65, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_PROXIMAL_FB = 66, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_INTERMEDIATE_FB = 67, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_DISTAL_FB = 68, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_TIP_FB = 69, + XR_BODY_JOINT_COUNT_FB = 70, + XR_BODY_JOINT_NONE_FB = -1, + XR_BODY_JOINT_MAX_ENUM_FB = 0x7FFFFFFF +} XrBodyJointFB; + +typedef enum XrBodyJointSetFB { + XR_BODY_JOINT_SET_DEFAULT_FB = 0, + XR_BODY_JOINT_SET_MAX_ENUM_FB = 0x7FFFFFFF +} XrBodyJointSetFB; +typedef struct XrBodyJointLocationFB { + XrSpaceLocationFlags locationFlags; + XrPosef pose; +} XrBodyJointLocationFB; + +// XrSystemBodyTrackingPropertiesFB extends XrSystemProperties +typedef struct XrSystemBodyTrackingPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsBodyTracking; +} XrSystemBodyTrackingPropertiesFB; + +typedef struct XrBodyTrackerCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBodyJointSetFB bodyJointSet; +} XrBodyTrackerCreateInfoFB; + +typedef struct XrBodySkeletonJointFB { + int32_t joint; + int32_t parentJoint; + XrPosef pose; +} XrBodySkeletonJointFB; + +typedef struct XrBodySkeletonFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t jointCount; + XrBodySkeletonJointFB* joints; +} XrBodySkeletonFB; + +typedef struct XrBodyJointsLocateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; +} XrBodyJointsLocateInfoFB; + +typedef struct XrBodyJointLocationsFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 isActive; + float confidence; + uint32_t jointCount; + XrBodyJointLocationFB* jointLocations; + uint32_t skeletonChangedCount; + XrTime time; +} XrBodyJointLocationsFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateBodyTrackerFB)(XrSession session, const XrBodyTrackerCreateInfoFB* createInfo, XrBodyTrackerFB* bodyTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyBodyTrackerFB)(XrBodyTrackerFB bodyTracker); +typedef XrResult (XRAPI_PTR *PFN_xrLocateBodyJointsFB)(XrBodyTrackerFB bodyTracker, const XrBodyJointsLocateInfoFB* locateInfo, XrBodyJointLocationsFB* locations); +typedef XrResult (XRAPI_PTR *PFN_xrGetBodySkeletonFB)(XrBodyTrackerFB bodyTracker, XrBodySkeletonFB* skeleton); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateBodyTrackerFB( + XrSession session, + const XrBodyTrackerCreateInfoFB* createInfo, + XrBodyTrackerFB* bodyTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyBodyTrackerFB( + XrBodyTrackerFB bodyTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrLocateBodyJointsFB( + XrBodyTrackerFB bodyTracker, + const XrBodyJointsLocateInfoFB* locateInfo, + XrBodyJointLocationsFB* locations); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetBodySkeletonFB( + XrBodyTrackerFB bodyTracker, + XrBodySkeletonFB* skeleton); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + #define XR_EXT_dpad_binding 1 #define XR_EXT_dpad_binding_SPEC_VERSION 1 #define XR_EXT_DPAD_BINDING_EXTENSION_NAME "XR_EXT_dpad_binding" @@ -3325,12 +3574,13 @@ typedef struct XrHandTrackingCapsulesStateFB { #define XR_FB_spatial_entity 1 XR_DEFINE_ATOM(XrAsyncRequestIdFB) #define XR_UUID_SIZE_EXT 16 -#define XR_FB_spatial_entity_SPEC_VERSION 1 +#define XR_FB_spatial_entity_SPEC_VERSION 2 #define XR_FB_SPATIAL_ENTITY_EXTENSION_NAME "XR_FB_spatial_entity" typedef enum XrSpaceComponentTypeFB { XR_SPACE_COMPONENT_TYPE_LOCATABLE_FB = 0, XR_SPACE_COMPONENT_TYPE_STORABLE_FB = 1, + XR_SPACE_COMPONENT_TYPE_SHARABLE_FB = 2, XR_SPACE_COMPONENT_TYPE_BOUNDED_2D_FB = 3, XR_SPACE_COMPONENT_TYPE_BOUNDED_3D_FB = 4, XR_SPACE_COMPONENT_TYPE_SEMANTIC_LABELS_FB = 5, @@ -3834,7 +4084,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGeometryInstanceSetTransformFB( #define XR_NULL_RENDER_MODEL_KEY_FB 0 XR_DEFINE_ATOM(XrRenderModelKeyFB) -#define XR_FB_render_model_SPEC_VERSION 3 +#define XR_FB_render_model_SPEC_VERSION 4 #define XR_FB_RENDER_MODEL_EXTENSION_NAME "XR_FB_render_model" #define XR_MAX_RENDER_MODEL_NAME_SIZE_FB 64 typedef XrFlags64 XrRenderModelFlagsFB; @@ -3913,7 +4163,7 @@ XRAPI_ATTR XrResult XRAPI_CALL xrLoadRenderModelFB( #define XR_VARJO_foveated_rendering 1 -#define XR_VARJO_foveated_rendering_SPEC_VERSION 2 +#define XR_VARJO_foveated_rendering_SPEC_VERSION 3 #define XR_VARJO_FOVEATED_RENDERING_EXTENSION_NAME "XR_VARJO_foveated_rendering" // XrViewLocateFoveatedRenderingVARJO extends XrViewLocateInfo typedef struct XrViewLocateFoveatedRenderingVARJO { @@ -4045,6 +4295,43 @@ XRAPI_ATTR XrResult XRAPI_CALL xrSetViewOffsetVARJO( #define XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_ML_ml2_controller_interaction" +#define XR_ML_frame_end_info 1 +#define XR_ML_frame_end_info_SPEC_VERSION 1 +#define XR_ML_FRAME_END_INFO_EXTENSION_NAME "XR_ML_frame_end_info" +typedef XrFlags64 XrFrameEndInfoFlagsML; + +// Flag bits for XrFrameEndInfoFlagsML +static const XrFrameEndInfoFlagsML XR_FRAME_END_INFO_PROTECTED_BIT_ML = 0x00000001; +static const XrFrameEndInfoFlagsML XR_FRAME_END_INFO_VIGNETTE_BIT_ML = 0x00000002; + +// XrFrameEndInfoML extends XrFrameEndInfo +typedef struct XrFrameEndInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float focusDistance; + XrFrameEndInfoFlagsML flags; +} XrFrameEndInfoML; + + + +#define XR_ML_global_dimmer 1 +#define XR_ML_global_dimmer_SPEC_VERSION 1 +#define XR_ML_GLOBAL_DIMMER_EXTENSION_NAME "XR_ML_global_dimmer" +typedef XrFlags64 XrGlobalDimmerFrameEndInfoFlagsML; + +// Flag bits for XrGlobalDimmerFrameEndInfoFlagsML +static const XrGlobalDimmerFrameEndInfoFlagsML XR_GLOBAL_DIMMER_FRAME_END_INFO_ENABLED_BIT_ML = 0x00000001; + +// XrGlobalDimmerFrameEndInfoML extends XrFrameEndInfo +typedef struct XrGlobalDimmerFrameEndInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float dimmerValue; + XrGlobalDimmerFrameEndInfoFlagsML flags; +} XrGlobalDimmerFrameEndInfoML; + + + #define XR_MSFT_spatial_anchor_persistence 1 XR_DEFINE_HANDLE(XrSpatialAnchorStoreConnectionMSFT) #define XR_MAX_SPATIAL_ANCHOR_NAME_SIZE_MSFT 256 @@ -4161,6 +4448,7 @@ typedef enum XrSpaceQueryActionFB { typedef enum XrSpaceStorageLocationFB { XR_SPACE_STORAGE_LOCATION_INVALID_FB = 0, XR_SPACE_STORAGE_LOCATION_LOCAL_FB = 1, + XR_SPACE_STORAGE_LOCATION_CLOUD_FB = 2, XR_SPACE_STORAGE_LOCATION_MAX_ENUM_FB = 0x7FFFFFFF } XrSpaceStorageLocationFB; typedef struct XR_MAY_ALIAS XrSpaceQueryInfoBaseHeaderFB { @@ -4309,6 +4597,43 @@ XRAPI_ATTR XrResult XRAPI_CALL xrEraseSpaceFB( #endif /* !XR_NO_PROTOTYPES */ +#define XR_FB_touch_controller_pro 1 +#define XR_FB_touch_controller_pro_SPEC_VERSION 1 +#define XR_FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME "XR_FB_touch_controller_pro" + + +#define XR_FB_spatial_entity_sharing 1 +XR_DEFINE_HANDLE(XrSpaceUserFB) +#define XR_FB_spatial_entity_sharing_SPEC_VERSION 1 +#define XR_FB_SPATIAL_ENTITY_SHARING_EXTENSION_NAME "XR_FB_spatial_entity_sharing" +typedef struct XrSpaceShareInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t spaceCount; + XrSpace* spaces; + uint32_t userCount; + XrSpaceUserFB* users; +} XrSpaceShareInfoFB; + +typedef struct XrEventDataSpaceShareCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSpaceShareCompleteFB; + +typedef XrResult (XRAPI_PTR *PFN_xrShareSpacesFB)(XrSession session, const XrSpaceShareInfoFB* info, XrAsyncRequestIdFB* requestId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrShareSpacesFB( + XrSession session, + const XrSpaceShareInfoFB* info, + XrAsyncRequestIdFB* requestId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + #define XR_FB_space_warp 1 #define XR_FB_space_warp_SPEC_VERSION 2 #define XR_FB_SPACE_WARP_EXTENSION_NAME "XR_FB_space_warp" @@ -4341,9 +4666,31 @@ typedef struct XrSystemSpaceWarpPropertiesFB { +#define XR_FB_haptic_amplitude_envelope 1 + +#define XR_MAX_HAPTIC_AMPLITUDE_ENVELOPE_SAMPLES_FB 4000u + +#define XR_FB_haptic_amplitude_envelope_SPEC_VERSION 1 +#define XR_FB_HAPTIC_AMPLITUDE_ENVELOPE_EXTENSION_NAME "XR_FB_haptic_amplitude_envelope" +typedef struct XrHapticAmplitudeEnvelopeVibrationFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrDuration duration; + uint32_t amplitudeCount; + const float* amplitudes; +} XrHapticAmplitudeEnvelopeVibrationFB; + + + #define XR_FB_scene 1 -#define XR_FB_scene_SPEC_VERSION 1 +#define XR_FB_scene_SPEC_VERSION 3 #define XR_FB_SCENE_EXTENSION_NAME "XR_FB_scene" +typedef XrFlags64 XrSemanticLabelsSupportFlagsFB; + +// Flag bits for XrSemanticLabelsSupportFlagsFB +static const XrSemanticLabelsSupportFlagsFB XR_SEMANTIC_LABELS_SUPPORT_MULTIPLE_SEMANTIC_LABELS_BIT_FB = 0x00000001; +static const XrSemanticLabelsSupportFlagsFB XR_SEMANTIC_LABELS_SUPPORT_ACCEPT_DESK_TO_TABLE_MIGRATION_BIT_FB = 0x00000002; + typedef struct XrExtent3DfFB { float width; float height; @@ -4387,6 +4734,13 @@ typedef struct XrBoundary2DFB { XrVector2f* vertices; } XrBoundary2DFB; +typedef struct XrSemanticLabelsSupportInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSemanticLabelsSupportFlagsFB flags; + const char* recognizedLabels; +} XrSemanticLabelsSupportInfoFB; + typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceBoundingBox2DFB)(XrSession session, XrSpace space, XrRect2Df* boundingBox2DOutput); typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceBoundingBox3DFB)(XrSession session, XrSpace space, XrRect3DfFB* boundingBox3DOutput); typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceSemanticLabelsFB)(XrSession session, XrSpace space, XrSemanticLabelsFB* semanticLabelsOutput); @@ -4453,6 +4807,35 @@ XRAPI_ATTR XrResult XRAPI_CALL xrSetDigitalLensControlALMALENCE( #endif /* !XR_NO_PROTOTYPES */ +#define XR_FB_scene_capture 1 +#define XR_FB_scene_capture_SPEC_VERSION 1 +#define XR_FB_SCENE_CAPTURE_EXTENSION_NAME "XR_FB_scene_capture" +typedef struct XrEventDataSceneCaptureCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSceneCaptureCompleteFB; + +typedef struct XrSceneCaptureRequestInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t requestByteCount; + const char* request; +} XrSceneCaptureRequestInfoFB; + +typedef XrResult (XRAPI_PTR *PFN_xrRequestSceneCaptureFB)(XrSession session, const XrSceneCaptureRequestInfoFB* info, XrAsyncRequestIdFB* requestId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrRequestSceneCaptureFB( + XrSession session, + const XrSceneCaptureRequestInfoFB* info, + XrAsyncRequestIdFB* requestId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + #define XR_FB_spatial_entity_container 1 #define XR_FB_spatial_entity_container_SPEC_VERSION 2 #define XR_FB_SPATIAL_ENTITY_CONTAINER_EXTENSION_NAME "XR_FB_spatial_entity_container" @@ -4476,6 +4859,260 @@ XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceContainerFB( #endif /* !XR_NO_PROTOTYPES */ +#define XR_META_foveation_eye_tracked 1 +#define XR_FOVEATION_CENTER_SIZE_META 2 +#define XR_META_foveation_eye_tracked_SPEC_VERSION 1 +#define XR_META_FOVEATION_EYE_TRACKED_EXTENSION_NAME "XR_META_foveation_eye_tracked" +typedef XrFlags64 XrFoveationEyeTrackedProfileCreateFlagsMETA; + +// Flag bits for XrFoveationEyeTrackedProfileCreateFlagsMETA + +typedef XrFlags64 XrFoveationEyeTrackedStateFlagsMETA; + +// Flag bits for XrFoveationEyeTrackedStateFlagsMETA +static const XrFoveationEyeTrackedStateFlagsMETA XR_FOVEATION_EYE_TRACKED_STATE_VALID_BIT_META = 0x00000001; + +// XrFoveationEyeTrackedProfileCreateInfoMETA extends XrFoveationLevelProfileCreateInfoFB +typedef struct XrFoveationEyeTrackedProfileCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFoveationEyeTrackedProfileCreateFlagsMETA flags; +} XrFoveationEyeTrackedProfileCreateInfoMETA; + +typedef struct XrFoveationEyeTrackedStateMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrVector2f foveationCenter[XR_FOVEATION_CENTER_SIZE_META]; + XrFoveationEyeTrackedStateFlagsMETA flags; +} XrFoveationEyeTrackedStateMETA; + +// XrSystemFoveationEyeTrackedPropertiesMETA extends XrSystemProperties +typedef struct XrSystemFoveationEyeTrackedPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsFoveationEyeTracked; +} XrSystemFoveationEyeTrackedPropertiesMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrGetFoveationEyeTrackedStateMETA)(XrSession session, XrFoveationEyeTrackedStateMETA* foveationState); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetFoveationEyeTrackedStateMETA( + XrSession session, + XrFoveationEyeTrackedStateMETA* foveationState); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_face_tracking 1 + +#define XR_FACE_EXPRESSSION_SET_DEFAULT_FB XR_FACE_EXPRESSION_SET_DEFAULT_FB + +XR_DEFINE_HANDLE(XrFaceTrackerFB) +#define XR_FB_face_tracking_SPEC_VERSION 1 +#define XR_FB_FACE_TRACKING_EXTENSION_NAME "XR_FB_face_tracking" + +typedef enum XrFaceExpressionFB { + XR_FACE_EXPRESSION_BROW_LOWERER_L_FB = 0, + XR_FACE_EXPRESSION_BROW_LOWERER_R_FB = 1, + XR_FACE_EXPRESSION_CHEEK_PUFF_L_FB = 2, + XR_FACE_EXPRESSION_CHEEK_PUFF_R_FB = 3, + XR_FACE_EXPRESSION_CHEEK_RAISER_L_FB = 4, + XR_FACE_EXPRESSION_CHEEK_RAISER_R_FB = 5, + XR_FACE_EXPRESSION_CHEEK_SUCK_L_FB = 6, + XR_FACE_EXPRESSION_CHEEK_SUCK_R_FB = 7, + XR_FACE_EXPRESSION_CHIN_RAISER_B_FB = 8, + XR_FACE_EXPRESSION_CHIN_RAISER_T_FB = 9, + XR_FACE_EXPRESSION_DIMPLER_L_FB = 10, + XR_FACE_EXPRESSION_DIMPLER_R_FB = 11, + XR_FACE_EXPRESSION_EYES_CLOSED_L_FB = 12, + XR_FACE_EXPRESSION_EYES_CLOSED_R_FB = 13, + XR_FACE_EXPRESSION_EYES_LOOK_DOWN_L_FB = 14, + XR_FACE_EXPRESSION_EYES_LOOK_DOWN_R_FB = 15, + XR_FACE_EXPRESSION_EYES_LOOK_LEFT_L_FB = 16, + XR_FACE_EXPRESSION_EYES_LOOK_LEFT_R_FB = 17, + XR_FACE_EXPRESSION_EYES_LOOK_RIGHT_L_FB = 18, + XR_FACE_EXPRESSION_EYES_LOOK_RIGHT_R_FB = 19, + XR_FACE_EXPRESSION_EYES_LOOK_UP_L_FB = 20, + XR_FACE_EXPRESSION_EYES_LOOK_UP_R_FB = 21, + XR_FACE_EXPRESSION_INNER_BROW_RAISER_L_FB = 22, + XR_FACE_EXPRESSION_INNER_BROW_RAISER_R_FB = 23, + XR_FACE_EXPRESSION_JAW_DROP_FB = 24, + XR_FACE_EXPRESSION_JAW_SIDEWAYS_LEFT_FB = 25, + XR_FACE_EXPRESSION_JAW_SIDEWAYS_RIGHT_FB = 26, + XR_FACE_EXPRESSION_JAW_THRUST_FB = 27, + XR_FACE_EXPRESSION_LID_TIGHTENER_L_FB = 28, + XR_FACE_EXPRESSION_LID_TIGHTENER_R_FB = 29, + XR_FACE_EXPRESSION_LIP_CORNER_DEPRESSOR_L_FB = 30, + XR_FACE_EXPRESSION_LIP_CORNER_DEPRESSOR_R_FB = 31, + XR_FACE_EXPRESSION_LIP_CORNER_PULLER_L_FB = 32, + XR_FACE_EXPRESSION_LIP_CORNER_PULLER_R_FB = 33, + XR_FACE_EXPRESSION_LIP_FUNNELER_LB_FB = 34, + XR_FACE_EXPRESSION_LIP_FUNNELER_LT_FB = 35, + XR_FACE_EXPRESSION_LIP_FUNNELER_RB_FB = 36, + XR_FACE_EXPRESSION_LIP_FUNNELER_RT_FB = 37, + XR_FACE_EXPRESSION_LIP_PRESSOR_L_FB = 38, + XR_FACE_EXPRESSION_LIP_PRESSOR_R_FB = 39, + XR_FACE_EXPRESSION_LIP_PUCKER_L_FB = 40, + XR_FACE_EXPRESSION_LIP_PUCKER_R_FB = 41, + XR_FACE_EXPRESSION_LIP_STRETCHER_L_FB = 42, + XR_FACE_EXPRESSION_LIP_STRETCHER_R_FB = 43, + XR_FACE_EXPRESSION_LIP_SUCK_LB_FB = 44, + XR_FACE_EXPRESSION_LIP_SUCK_LT_FB = 45, + XR_FACE_EXPRESSION_LIP_SUCK_RB_FB = 46, + XR_FACE_EXPRESSION_LIP_SUCK_RT_FB = 47, + XR_FACE_EXPRESSION_LIP_TIGHTENER_L_FB = 48, + XR_FACE_EXPRESSION_LIP_TIGHTENER_R_FB = 49, + XR_FACE_EXPRESSION_LIPS_TOWARD_FB = 50, + XR_FACE_EXPRESSION_LOWER_LIP_DEPRESSOR_L_FB = 51, + XR_FACE_EXPRESSION_LOWER_LIP_DEPRESSOR_R_FB = 52, + XR_FACE_EXPRESSION_MOUTH_LEFT_FB = 53, + XR_FACE_EXPRESSION_MOUTH_RIGHT_FB = 54, + XR_FACE_EXPRESSION_NOSE_WRINKLER_L_FB = 55, + XR_FACE_EXPRESSION_NOSE_WRINKLER_R_FB = 56, + XR_FACE_EXPRESSION_OUTER_BROW_RAISER_L_FB = 57, + XR_FACE_EXPRESSION_OUTER_BROW_RAISER_R_FB = 58, + XR_FACE_EXPRESSION_UPPER_LID_RAISER_L_FB = 59, + XR_FACE_EXPRESSION_UPPER_LID_RAISER_R_FB = 60, + XR_FACE_EXPRESSION_UPPER_LIP_RAISER_L_FB = 61, + XR_FACE_EXPRESSION_UPPER_LIP_RAISER_R_FB = 62, + XR_FACE_EXPRESSION_COUNT_FB = 63, + XR_FACE_EXPRESSION_MAX_ENUM_FB = 0x7FFFFFFF +} XrFaceExpressionFB; + +typedef enum XrFaceExpressionSetFB { + XR_FACE_EXPRESSION_SET_DEFAULT_FB = 0, + XR_FACE_EXPRESSION_SET_MAX_ENUM_FB = 0x7FFFFFFF +} XrFaceExpressionSetFB; + +typedef enum XrFaceConfidenceFB { + XR_FACE_CONFIDENCE_LOWER_FACE_FB = 0, + XR_FACE_CONFIDENCE_UPPER_FACE_FB = 1, + XR_FACE_CONFIDENCE_COUNT_FB = 2, + XR_FACE_CONFIDENCE_MAX_ENUM_FB = 0x7FFFFFFF +} XrFaceConfidenceFB; +// XrSystemFaceTrackingPropertiesFB extends XrSystemProperties +typedef struct XrSystemFaceTrackingPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsFaceTracking; +} XrSystemFaceTrackingPropertiesFB; + +typedef struct XrFaceTrackerCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFaceExpressionSetFB faceExpressionSet; +} XrFaceTrackerCreateInfoFB; + +typedef struct XrFaceExpressionInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime time; +} XrFaceExpressionInfoFB; + +typedef struct XrFaceExpressionStatusFB { + XrBool32 isValid; + XrBool32 isEyeFollowingBlendshapesValid; +} XrFaceExpressionStatusFB; + +typedef struct XrFaceExpressionWeightsFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t weightCount; + float* weights; + uint32_t confidenceCount; + float* confidences; + XrFaceExpressionStatusFB status; + XrTime time; +} XrFaceExpressionWeightsFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateFaceTrackerFB)(XrSession session, const XrFaceTrackerCreateInfoFB* createInfo, XrFaceTrackerFB* faceTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyFaceTrackerFB)(XrFaceTrackerFB faceTracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetFaceExpressionWeightsFB)(XrFaceTrackerFB faceTracker, const XrFaceExpressionInfoFB* expressionInfo, XrFaceExpressionWeightsFB* expressionWeights); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateFaceTrackerFB( + XrSession session, + const XrFaceTrackerCreateInfoFB* createInfo, + XrFaceTrackerFB* faceTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyFaceTrackerFB( + XrFaceTrackerFB faceTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetFaceExpressionWeightsFB( + XrFaceTrackerFB faceTracker, + const XrFaceExpressionInfoFB* expressionInfo, + XrFaceExpressionWeightsFB* expressionWeights); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_eye_tracking_social 1 +XR_DEFINE_HANDLE(XrEyeTrackerFB) +#define XR_FB_eye_tracking_social_SPEC_VERSION 1 +#define XR_FB_EYE_TRACKING_SOCIAL_EXTENSION_NAME "XR_FB_eye_tracking_social" + +typedef enum XrEyePositionFB { + XR_EYE_POSITION_LEFT_FB = 0, + XR_EYE_POSITION_RIGHT_FB = 1, + XR_EYE_POSITION_COUNT_FB = 2, + XR_EYE_POSITION_MAX_ENUM_FB = 0x7FFFFFFF +} XrEyePositionFB; +typedef struct XrEyeGazeFB { + XrBool32 isValid; + XrPosef gazePose; + float gazeConfidence; +} XrEyeGazeFB; + +typedef struct XrEyeTrackerCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrEyeTrackerCreateInfoFB; + +typedef struct XrEyeGazesInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; +} XrEyeGazesInfoFB; + +// XrSystemEyeTrackingPropertiesFB extends XrSystemProperties +typedef struct XrSystemEyeTrackingPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsEyeTracking; +} XrSystemEyeTrackingPropertiesFB; + +typedef struct XrEyeGazesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrEyeGazeFB gaze[XR_EYE_POSITION_COUNT_FB]; + XrTime time; +} XrEyeGazesFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateEyeTrackerFB)(XrSession session, const XrEyeTrackerCreateInfoFB* createInfo, XrEyeTrackerFB* eyeTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyEyeTrackerFB)(XrEyeTrackerFB eyeTracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetEyeGazesFB)(XrEyeTrackerFB eyeTracker, const XrEyeGazesInfoFB* gazeInfo, XrEyeGazesFB* eyeGazes); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateEyeTrackerFB( + XrSession session, + const XrEyeTrackerCreateInfoFB* createInfo, + XrEyeTrackerFB* eyeTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyEyeTrackerFB( + XrEyeTrackerFB eyeTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetEyeGazesFB( + XrEyeTrackerFB eyeTracker, + const XrEyeGazesInfoFB* gazeInfo, + XrEyeGazesFB* eyeGazes); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + #define XR_FB_passthrough_keyboard_hands 1 #define XR_FB_passthrough_keyboard_hands_SPEC_VERSION 2 #define XR_FB_PASSTHROUGH_KEYBOARD_HANDS_EXTENSION_NAME "XR_FB_passthrough_keyboard_hands" @@ -4517,6 +5154,349 @@ typedef struct XrCompositionLayerSettingsFB { +#define XR_FB_touch_controller_proximity 1 +#define XR_FB_touch_controller_proximity_SPEC_VERSION 1 +#define XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME "XR_FB_touch_controller_proximity" + + +#define XR_FB_haptic_pcm 1 + +#define XR_MAX_HAPTIC_PCM_BUFFER_SIZE_FB 4000 + +#define XR_FB_haptic_pcm_SPEC_VERSION 1 +#define XR_FB_HAPTIC_PCM_EXTENSION_NAME "XR_FB_haptic_pcm" +typedef struct XrHapticPcmVibrationFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t bufferSize; + const float* buffer; + float sampleRate; + XrBool32 append; + uint32_t* samplesConsumed; +} XrHapticPcmVibrationFB; + +typedef struct XrDevicePcmSampleRateStateFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + float sampleRate; +} XrDevicePcmSampleRateStateFB; + +typedef XrDevicePcmSampleRateStateFB XrDevicePcmSampleRateGetInfoFB; + +typedef XrResult (XRAPI_PTR *PFN_xrGetDeviceSampleRateFB)(XrSession session, const XrHapticActionInfo* hapticActionInfo, XrDevicePcmSampleRateGetInfoFB* deviceSampleRate); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetDeviceSampleRateFB( + XrSession session, + const XrHapticActionInfo* hapticActionInfo, + XrDevicePcmSampleRateGetInfoFB* deviceSampleRate); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_composition_layer_depth_test 1 +#define XR_FB_composition_layer_depth_test_SPEC_VERSION 1 +#define XR_FB_COMPOSITION_LAYER_DEPTH_TEST_EXTENSION_NAME "XR_FB_composition_layer_depth_test" + +typedef enum XrCompareOpFB { + XR_COMPARE_OP_NEVER_FB = 0, + XR_COMPARE_OP_LESS_FB = 1, + XR_COMPARE_OP_EQUAL_FB = 2, + XR_COMPARE_OP_LESS_OR_EQUAL_FB = 3, + XR_COMPARE_OP_GREATER_FB = 4, + XR_COMPARE_OP_NOT_EQUAL_FB = 5, + XR_COMPARE_OP_GREATER_OR_EQUAL_FB = 6, + XR_COMPARE_OP_ALWAYS_FB = 7, + XR_COMPARE_OP_MAX_ENUM_FB = 0x7FFFFFFF +} XrCompareOpFB; +// XrCompositionLayerDepthTestFB extends XrCompositionLayerBaseHeader +typedef struct XrCompositionLayerDepthTestFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 depthMask; + XrCompareOpFB compareOp; +} XrCompositionLayerDepthTestFB; + + + +#define XR_META_local_dimming 1 +#define XR_META_local_dimming_SPEC_VERSION 1 +#define XR_META_LOCAL_DIMMING_EXTENSION_NAME "XR_META_local_dimming" + +typedef enum XrLocalDimmingModeMETA { + XR_LOCAL_DIMMING_MODE_OFF_META = 0, + XR_LOCAL_DIMMING_MODE_ON_META = 1, + XR_LOCAL_DIMMING_MODE_MAX_ENUM_META = 0x7FFFFFFF +} XrLocalDimmingModeMETA; +// XrLocalDimmingFrameEndInfoMETA extends XrFrameEndInfo +typedef struct XrLocalDimmingFrameEndInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrLocalDimmingModeMETA localDimmingMode; +} XrLocalDimmingFrameEndInfoMETA; + + + +#define XR_META_virtual_keyboard 1 +XR_DEFINE_HANDLE(XrVirtualKeyboardMETA) +#define XR_MAX_VIRTUAL_KEYBOARD_COMMIT_TEXT_SIZE_META 3992 +#define XR_META_virtual_keyboard_SPEC_VERSION 1 +#define XR_META_VIRTUAL_KEYBOARD_EXTENSION_NAME "XR_META_virtual_keyboard" + +typedef enum XrVirtualKeyboardLocationTypeMETA { + XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_CUSTOM_META = 0, + XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_FAR_META = 1, + XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_DIRECT_META = 2, + XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_MAX_ENUM_META = 0x7FFFFFFF +} XrVirtualKeyboardLocationTypeMETA; + +typedef enum XrVirtualKeyboardInputSourceMETA { + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_RAY_LEFT_META = 1, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_RAY_RIGHT_META = 2, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_RAY_LEFT_META = 3, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_RAY_RIGHT_META = 4, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_DIRECT_LEFT_META = 5, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_DIRECT_RIGHT_META = 6, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_DIRECT_INDEX_TIP_LEFT_META = 7, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_DIRECT_INDEX_TIP_RIGHT_META = 8, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_MAX_ENUM_META = 0x7FFFFFFF +} XrVirtualKeyboardInputSourceMETA; +typedef XrFlags64 XrVirtualKeyboardInputStateFlagsMETA; + +// Flag bits for XrVirtualKeyboardInputStateFlagsMETA +static const XrVirtualKeyboardInputStateFlagsMETA XR_VIRTUAL_KEYBOARD_INPUT_STATE_PRESSED_BIT_META = 0x00000001; + +// XrSystemVirtualKeyboardPropertiesMETA extends XrSystemProperties +typedef struct XrSystemVirtualKeyboardPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsVirtualKeyboard; +} XrSystemVirtualKeyboardPropertiesMETA; + +typedef struct XrVirtualKeyboardCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrVirtualKeyboardCreateInfoMETA; + +typedef struct XrVirtualKeyboardSpaceCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardLocationTypeMETA locationType; + XrSpace space; + XrPosef poseInSpace; +} XrVirtualKeyboardSpaceCreateInfoMETA; + +typedef struct XrVirtualKeyboardLocationInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardLocationTypeMETA locationType; + XrSpace space; + XrPosef poseInSpace; + float scale; +} XrVirtualKeyboardLocationInfoMETA; + +typedef struct XrVirtualKeyboardModelVisibilitySetInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 visible; +} XrVirtualKeyboardModelVisibilitySetInfoMETA; + +typedef struct XrVirtualKeyboardAnimationStateMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + int32_t animationIndex; + float fraction; +} XrVirtualKeyboardAnimationStateMETA; + +typedef struct XrVirtualKeyboardModelAnimationStatesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t stateCapacityInput; + uint32_t stateCountOutput; + XrVirtualKeyboardAnimationStateMETA* states; +} XrVirtualKeyboardModelAnimationStatesMETA; + +typedef struct XrVirtualKeyboardTextureDataMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t textureWidth; + uint32_t textureHeight; + uint32_t bufferCapacityInput; + uint32_t bufferCountOutput; + uint8_t* buffer; +} XrVirtualKeyboardTextureDataMETA; + +typedef struct XrVirtualKeyboardInputInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardInputSourceMETA inputSource; + XrSpace inputSpace; + XrPosef inputPoseInSpace; + XrVirtualKeyboardInputStateFlagsMETA inputState; +} XrVirtualKeyboardInputInfoMETA; + +typedef struct XrVirtualKeyboardTextContextChangeInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + const char* textContext; +} XrVirtualKeyboardTextContextChangeInfoMETA; + +typedef struct XrEventDataVirtualKeyboardCommitTextMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; + char text[XR_MAX_VIRTUAL_KEYBOARD_COMMIT_TEXT_SIZE_META]; +} XrEventDataVirtualKeyboardCommitTextMETA; + +typedef struct XrEventDataVirtualKeyboardBackspaceMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; +} XrEventDataVirtualKeyboardBackspaceMETA; + +typedef struct XrEventDataVirtualKeyboardEnterMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; +} XrEventDataVirtualKeyboardEnterMETA; + +typedef struct XrEventDataVirtualKeyboardShownMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; +} XrEventDataVirtualKeyboardShownMETA; + +typedef struct XrEventDataVirtualKeyboardHiddenMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; +} XrEventDataVirtualKeyboardHiddenMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateVirtualKeyboardMETA)(XrSession session, const XrVirtualKeyboardCreateInfoMETA* createInfo, XrVirtualKeyboardMETA* keyboard); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyVirtualKeyboardMETA)(XrVirtualKeyboardMETA keyboard); +typedef XrResult (XRAPI_PTR *PFN_xrCreateVirtualKeyboardSpaceMETA)(XrSession session, XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardSpaceCreateInfoMETA* createInfo, XrSpace* keyboardSpace); +typedef XrResult (XRAPI_PTR *PFN_xrSuggestVirtualKeyboardLocationMETA)(XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardLocationInfoMETA* locationInfo); +typedef XrResult (XRAPI_PTR *PFN_xrGetVirtualKeyboardScaleMETA)(XrVirtualKeyboardMETA keyboard, float* scale); +typedef XrResult (XRAPI_PTR *PFN_xrSetVirtualKeyboardModelVisibilityMETA)(XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardModelVisibilitySetInfoMETA* modelVisibility); +typedef XrResult (XRAPI_PTR *PFN_xrGetVirtualKeyboardModelAnimationStatesMETA)(XrVirtualKeyboardMETA keyboard, XrVirtualKeyboardModelAnimationStatesMETA* animationStates); +typedef XrResult (XRAPI_PTR *PFN_xrGetVirtualKeyboardDirtyTexturesMETA)(XrVirtualKeyboardMETA keyboard, uint32_t textureIdCapacityInput, uint32_t* textureIdCountOutput, uint64_t* textureIds); +typedef XrResult (XRAPI_PTR *PFN_xrGetVirtualKeyboardTextureDataMETA)(XrVirtualKeyboardMETA keyboard, uint64_t textureId, XrVirtualKeyboardTextureDataMETA* textureData); +typedef XrResult (XRAPI_PTR *PFN_xrSendVirtualKeyboardInputMETA)(XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardInputInfoMETA* info, XrPosef* interactorRootPose); +typedef XrResult (XRAPI_PTR *PFN_xrChangeVirtualKeyboardTextContextMETA)(XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardTextContextChangeInfoMETA* changeInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateVirtualKeyboardMETA( + XrSession session, + const XrVirtualKeyboardCreateInfoMETA* createInfo, + XrVirtualKeyboardMETA* keyboard); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyVirtualKeyboardMETA( + XrVirtualKeyboardMETA keyboard); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateVirtualKeyboardSpaceMETA( + XrSession session, + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardSpaceCreateInfoMETA* createInfo, + XrSpace* keyboardSpace); + +XRAPI_ATTR XrResult XRAPI_CALL xrSuggestVirtualKeyboardLocationMETA( + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardLocationInfoMETA* locationInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVirtualKeyboardScaleMETA( + XrVirtualKeyboardMETA keyboard, + float* scale); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetVirtualKeyboardModelVisibilityMETA( + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardModelVisibilitySetInfoMETA* modelVisibility); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVirtualKeyboardModelAnimationStatesMETA( + XrVirtualKeyboardMETA keyboard, + XrVirtualKeyboardModelAnimationStatesMETA* animationStates); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVirtualKeyboardDirtyTexturesMETA( + XrVirtualKeyboardMETA keyboard, + uint32_t textureIdCapacityInput, + uint32_t* textureIdCountOutput, + uint64_t* textureIds); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVirtualKeyboardTextureDataMETA( + XrVirtualKeyboardMETA keyboard, + uint64_t textureId, + XrVirtualKeyboardTextureDataMETA* textureData); + +XRAPI_ATTR XrResult XRAPI_CALL xrSendVirtualKeyboardInputMETA( + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardInputInfoMETA* info, + XrPosef* interactorRootPose); + +XRAPI_ATTR XrResult XRAPI_CALL xrChangeVirtualKeyboardTextContextMETA( + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardTextContextChangeInfoMETA* changeInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_OCULUS_external_camera 1 +#define XR_MAX_EXTERNAL_CAMERA_NAME_SIZE_OCULUS 32 +#define XR_OCULUS_external_camera_SPEC_VERSION 1 +#define XR_OCULUS_EXTERNAL_CAMERA_EXTENSION_NAME "XR_OCULUS_external_camera" + +typedef enum XrExternalCameraAttachedToDeviceOCULUS { + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_NONE_OCULUS = 0, + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_HMD_OCULUS = 1, + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_LTOUCH_OCULUS = 2, + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_RTOUCH_OCULUS = 3, + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_MAX_ENUM_OCULUS = 0x7FFFFFFF +} XrExternalCameraAttachedToDeviceOCULUS; +typedef XrFlags64 XrExternalCameraStatusFlagsOCULUS; + +// Flag bits for XrExternalCameraStatusFlagsOCULUS +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CONNECTED_BIT_OCULUS = 0x00000001; +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CALIBRATING_BIT_OCULUS = 0x00000002; +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CALIBRATION_FAILED_BIT_OCULUS = 0x00000004; +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CALIBRATED_BIT_OCULUS = 0x00000008; +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CAPTURING_BIT_OCULUS = 0x00000010; + +typedef struct XrExternalCameraIntrinsicsOCULUS { + XrTime lastChangeTime; + XrFovf fov; + float virtualNearPlaneDistance; + float virtualFarPlaneDistance; + XrExtent2Di imageSensorPixelResolution; +} XrExternalCameraIntrinsicsOCULUS; + +typedef struct XrExternalCameraExtrinsicsOCULUS { + XrTime lastChangeTime; + XrExternalCameraStatusFlagsOCULUS cameraStatusFlags; + XrExternalCameraAttachedToDeviceOCULUS attachedToDevice; + XrPosef relativePose; +} XrExternalCameraExtrinsicsOCULUS; + +typedef struct XrExternalCameraOCULUS { + XrStructureType type; + const void* XR_MAY_ALIAS next; + char name[XR_MAX_EXTERNAL_CAMERA_NAME_SIZE_OCULUS]; + XrExternalCameraIntrinsicsOCULUS intrinsics; + XrExternalCameraExtrinsicsOCULUS extrinsics; +} XrExternalCameraOCULUS; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateExternalCamerasOCULUS)(XrSession session, uint32_t cameraCapacityInput, uint32_t* cameraCountOutput, XrExternalCameraOCULUS* cameras); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateExternalCamerasOCULUS( + XrSession session, + uint32_t cameraCapacityInput, + uint32_t* cameraCountOutput, + XrExternalCameraOCULUS* cameras); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + #define XR_META_performance_metrics 1 #define XR_META_performance_metrics_SPEC_VERSION 2 #define XR_META_PERFORMANCE_METRICS_EXTENSION_NAME "XR_META_performance_metrics" @@ -4580,6 +5560,67 @@ XRAPI_ATTR XrResult XRAPI_CALL xrQueryPerformanceMetricsCounterMETA( #endif /* !XR_NO_PROTOTYPES */ +#define XR_FB_spatial_entity_storage_batch 1 +#define XR_FB_spatial_entity_storage_batch_SPEC_VERSION 1 +#define XR_FB_SPATIAL_ENTITY_STORAGE_BATCH_EXTENSION_NAME "XR_FB_spatial_entity_storage_batch" +typedef struct XrSpaceListSaveInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t spaceCount; + XrSpace* spaces; + XrSpaceStorageLocationFB location; +} XrSpaceListSaveInfoFB; + +typedef struct XrEventDataSpaceListSaveCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSpaceListSaveCompleteFB; + +typedef XrResult (XRAPI_PTR *PFN_xrSaveSpaceListFB)(XrSession session, const XrSpaceListSaveInfoFB* info, XrAsyncRequestIdFB* requestId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSaveSpaceListFB( + XrSession session, + const XrSpaceListSaveInfoFB* info, + XrAsyncRequestIdFB* requestId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_spatial_entity_user 1 +typedef uint64_t XrSpaceUserIdFB; +#define XR_FB_spatial_entity_user_SPEC_VERSION 1 +#define XR_FB_SPATIAL_ENTITY_USER_EXTENSION_NAME "XR_FB_spatial_entity_user" +typedef struct XrSpaceUserCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpaceUserIdFB userId; +} XrSpaceUserCreateInfoFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpaceUserFB)(XrSession session, const XrSpaceUserCreateInfoFB* info, XrSpaceUserFB* user); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceUserIdFB)(XrSpaceUserFB user, XrSpaceUserIdFB* userId); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpaceUserFB)(XrSpaceUserFB user); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpaceUserFB( + XrSession session, + const XrSpaceUserCreateInfoFB* info, + XrSpaceUserFB* user); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceUserIdFB( + XrSpaceUserFB user, + XrSpaceUserIdFB* userId); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpaceUserFB( + XrSpaceUserFB user); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + #define XR_META_headset_id 1 #define XR_META_headset_id_SPEC_VERSION 1 #define XR_META_HEADSET_ID_EXTENSION_NAME "XR_META_headset_id" @@ -4592,11 +5633,119 @@ typedef struct XrSystemHeadsetIdPropertiesMETA { +#define XR_META_passthrough_color_lut 1 +XR_DEFINE_HANDLE(XrPassthroughColorLutMETA) +#define XR_META_passthrough_color_lut_SPEC_VERSION 1 +#define XR_META_PASSTHROUGH_COLOR_LUT_EXTENSION_NAME "XR_META_passthrough_color_lut" + +typedef enum XrPassthroughColorLutChannelsMETA { + XR_PASSTHROUGH_COLOR_LUT_CHANNELS_RGB_META = 1, + XR_PASSTHROUGH_COLOR_LUT_CHANNELS_RGBA_META = 2, + XR_PASSTHROUGH_COLOR_LUT_CHANNELS_MAX_ENUM_META = 0x7FFFFFFF +} XrPassthroughColorLutChannelsMETA; +typedef struct XrPassthroughColorLutDataMETA { + uint32_t bufferSize; + const uint8_t* buffer; +} XrPassthroughColorLutDataMETA; + +typedef struct XrPassthroughColorLutCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughColorLutChannelsMETA channels; + uint32_t resolution; + XrPassthroughColorLutDataMETA data; +} XrPassthroughColorLutCreateInfoMETA; + +typedef struct XrPassthroughColorLutUpdateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughColorLutDataMETA data; +} XrPassthroughColorLutUpdateInfoMETA; + +// XrPassthroughColorMapLutMETA extends XrPassthroughStyleFB +typedef struct XrPassthroughColorMapLutMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughColorLutMETA colorLut; + float weight; +} XrPassthroughColorMapLutMETA; + +// XrPassthroughColorMapInterpolatedLutMETA extends XrPassthroughStyleFB +typedef struct XrPassthroughColorMapInterpolatedLutMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughColorLutMETA sourceColorLut; + XrPassthroughColorLutMETA targetColorLut; + float weight; +} XrPassthroughColorMapInterpolatedLutMETA; + +// XrSystemPassthroughColorLutPropertiesMETA extends XrSystemProperties +typedef struct XrSystemPassthroughColorLutPropertiesMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t maxColorLutResolution; +} XrSystemPassthroughColorLutPropertiesMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrCreatePassthroughColorLutMETA)(XrPassthroughFB passthrough, const XrPassthroughColorLutCreateInfoMETA* createInfo, XrPassthroughColorLutMETA* colorLut); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPassthroughColorLutMETA)(XrPassthroughColorLutMETA colorLut); +typedef XrResult (XRAPI_PTR *PFN_xrUpdatePassthroughColorLutMETA)(XrPassthroughColorLutMETA colorLut, const XrPassthroughColorLutUpdateInfoMETA* updateInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePassthroughColorLutMETA( + XrPassthroughFB passthrough, + const XrPassthroughColorLutCreateInfoMETA* createInfo, + XrPassthroughColorLutMETA* colorLut); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPassthroughColorLutMETA( + XrPassthroughColorLutMETA colorLut); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdatePassthroughColorLutMETA( + XrPassthroughColorLutMETA colorLut, + const XrPassthroughColorLutUpdateInfoMETA* updateInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + #define XR_EXT_uuid 1 #define XR_EXT_uuid_SPEC_VERSION 1 #define XR_EXT_UUID_EXTENSION_NAME "XR_EXT_uuid" +#define XR_EXT_hand_interaction 1 +#define XR_EXT_hand_interaction_SPEC_VERSION 1 +#define XR_EXT_HAND_INTERACTION_EXTENSION_NAME "XR_EXT_hand_interaction" + + +#define XR_QCOM_tracking_optimization_settings 1 +#define XR_QCOM_tracking_optimization_settings_SPEC_VERSION 1 +#define XR_QCOM_TRACKING_OPTIMIZATION_SETTINGS_EXTENSION_NAME "XR_QCOM_tracking_optimization_settings" + +typedef enum XrTrackingOptimizationSettingsDomainQCOM { + XR_TRACKING_OPTIMIZATION_SETTINGS_DOMAIN_ALL_QCOM = 1, + XR_TRACKING_OPTIMIZATION_SETTINGS_DOMAIN_MAX_ENUM_QCOM = 0x7FFFFFFF +} XrTrackingOptimizationSettingsDomainQCOM; + +typedef enum XrTrackingOptimizationSettingsHintQCOM { + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_NONE_QCOM = 0, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_LONG_RANGE_PRIORIZATION_QCOM = 1, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_CLOSE_RANGE_PRIORIZATION_QCOM = 2, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_LOW_POWER_PRIORIZATION_QCOM = 3, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_HIGH_POWER_PRIORIZATION_QCOM = 4, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_MAX_ENUM_QCOM = 0x7FFFFFFF +} XrTrackingOptimizationSettingsHintQCOM; +typedef XrResult (XRAPI_PTR *PFN_xrSetTrackingOptimizationSettingsHintQCOM)(XrSession session, XrTrackingOptimizationSettingsDomainQCOM domain, XrTrackingOptimizationSettingsHintQCOM hint); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetTrackingOptimizationSettingsHintQCOM( + XrSession session, + XrTrackingOptimizationSettingsDomainQCOM domain, + XrTrackingOptimizationSettingsHintQCOM hint); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + #define XR_HTC_passthrough 1 XR_DEFINE_HANDLE(XrPassthroughHTC) #define XR_HTC_passthrough_SPEC_VERSION 1 @@ -4741,6 +5890,244 @@ typedef struct XrActiveActionSetPrioritiesEXT { } XrActiveActionSetPrioritiesEXT; + +#define XR_MNDX_force_feedback_curl 1 +#define XR_MNDX_force_feedback_curl_SPEC_VERSION 1 +#define XR_MNDX_FORCE_FEEDBACK_CURL_EXTENSION_NAME "XR_MNDX_force_feedback_curl" + +typedef enum XrForceFeedbackCurlLocationMNDX { + XR_FORCE_FEEDBACK_CURL_LOCATION_THUMB_CURL_MNDX = 0, + XR_FORCE_FEEDBACK_CURL_LOCATION_INDEX_CURL_MNDX = 1, + XR_FORCE_FEEDBACK_CURL_LOCATION_MIDDLE_CURL_MNDX = 2, + XR_FORCE_FEEDBACK_CURL_LOCATION_RING_CURL_MNDX = 3, + XR_FORCE_FEEDBACK_CURL_LOCATION_LITTLE_CURL_MNDX = 4, + XR_FORCE_FEEDBACK_CURL_LOCATION_MAX_ENUM_MNDX = 0x7FFFFFFF +} XrForceFeedbackCurlLocationMNDX; +// XrSystemForceFeedbackCurlPropertiesMNDX extends XrSystemProperties +typedef struct XrSystemForceFeedbackCurlPropertiesMNDX { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsForceFeedbackCurl; +} XrSystemForceFeedbackCurlPropertiesMNDX; + +typedef struct XrForceFeedbackCurlApplyLocationMNDX { + XrForceFeedbackCurlLocationMNDX location; + float value; +} XrForceFeedbackCurlApplyLocationMNDX; + +typedef struct XrForceFeedbackCurlApplyLocationsMNDX { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t locationCount; + XrForceFeedbackCurlApplyLocationMNDX* locations; +} XrForceFeedbackCurlApplyLocationsMNDX; + +typedef XrResult (XRAPI_PTR *PFN_xrApplyForceFeedbackCurlMNDX)(XrHandTrackerEXT handTracker, const XrForceFeedbackCurlApplyLocationsMNDX* locations); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrApplyForceFeedbackCurlMNDX( + XrHandTrackerEXT handTracker, + const XrForceFeedbackCurlApplyLocationsMNDX* locations); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_BD_controller_interaction 1 +#define XR_BD_controller_interaction_SPEC_VERSION 1 +#define XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_BD_controller_interaction" + + +#define XR_EXT_local_floor 1 +#define XR_EXT_local_floor_SPEC_VERSION 1 +#define XR_EXT_LOCAL_FLOOR_EXTENSION_NAME "XR_EXT_local_floor" + + +#define XR_EXT_hand_tracking_data_source 1 +#define XR_EXT_hand_tracking_data_source_SPEC_VERSION 1 +#define XR_EXT_HAND_TRACKING_DATA_SOURCE_EXTENSION_NAME "XR_EXT_hand_tracking_data_source" + +typedef enum XrHandTrackingDataSourceEXT { + XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT = 1, + XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT = 2, + XR_HAND_TRACKING_DATA_SOURCE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrHandTrackingDataSourceEXT; +// XrHandTrackingDataSourceInfoEXT extends XrHandTrackerCreateInfoEXT +typedef struct XrHandTrackingDataSourceInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t requestedDataSourceCount; + XrHandTrackingDataSourceEXT* requestedDataSources; +} XrHandTrackingDataSourceInfoEXT; + +// XrHandTrackingDataSourceStateEXT extends XrHandJointLocationsEXT +typedef struct XrHandTrackingDataSourceStateEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 isActive; + XrHandTrackingDataSourceEXT dataSource; +} XrHandTrackingDataSourceStateEXT; + + + +#define XR_EXT_plane_detection 1 +XR_DEFINE_HANDLE(XrPlaneDetectorEXT) +#define XR_EXT_plane_detection_SPEC_VERSION 1 +#define XR_EXT_PLANE_DETECTION_EXTENSION_NAME "XR_EXT_plane_detection" + +typedef enum XrPlaneDetectorOrientationEXT { + XR_PLANE_DETECTOR_ORIENTATION_HORIZONTAL_UPWARD_EXT = 0, + XR_PLANE_DETECTOR_ORIENTATION_HORIZONTAL_DOWNWARD_EXT = 1, + XR_PLANE_DETECTOR_ORIENTATION_VERTICAL_EXT = 2, + XR_PLANE_DETECTOR_ORIENTATION_ARBITRARY_EXT = 3, + XR_PLANE_DETECTOR_ORIENTATION_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPlaneDetectorOrientationEXT; + +typedef enum XrPlaneDetectorSemanticTypeEXT { + XR_PLANE_DETECTOR_SEMANTIC_TYPE_UNDEFINED_EXT = 0, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_CEILING_EXT = 1, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_FLOOR_EXT = 2, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_WALL_EXT = 3, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_PLATFORM_EXT = 4, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPlaneDetectorSemanticTypeEXT; + +typedef enum XrPlaneDetectionStateEXT { + XR_PLANE_DETECTION_STATE_NONE_EXT = 0, + XR_PLANE_DETECTION_STATE_PENDING_EXT = 1, + XR_PLANE_DETECTION_STATE_DONE_EXT = 2, + XR_PLANE_DETECTION_STATE_ERROR_EXT = 3, + XR_PLANE_DETECTION_STATE_FATAL_EXT = 4, + XR_PLANE_DETECTION_STATE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPlaneDetectionStateEXT; +typedef XrFlags64 XrPlaneDetectionCapabilityFlagsEXT; + +// Flag bits for XrPlaneDetectionCapabilityFlagsEXT +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_PLANE_DETECTION_BIT_EXT = 0x00000001; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_PLANE_HOLES_BIT_EXT = 0x00000002; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_CEILING_BIT_EXT = 0x00000004; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_FLOOR_BIT_EXT = 0x00000008; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_WALL_BIT_EXT = 0x00000010; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_PLATFORM_BIT_EXT = 0x00000020; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_ORIENTATION_BIT_EXT = 0x00000040; + +typedef XrFlags64 XrPlaneDetectorFlagsEXT; + +// Flag bits for XrPlaneDetectorFlagsEXT +static const XrPlaneDetectorFlagsEXT XR_PLANE_DETECTOR_ENABLE_CONTOUR_BIT_EXT = 0x00000001; + +// XrSystemPlaneDetectionPropertiesEXT extends XrSystemProperties +typedef struct XrSystemPlaneDetectionPropertiesEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPlaneDetectionCapabilityFlagsEXT supportedFeatures; +} XrSystemPlaneDetectionPropertiesEXT; + +typedef struct XrPlaneDetectorCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPlaneDetectorFlagsEXT flags; +} XrPlaneDetectorCreateInfoEXT; + +typedef struct XrExtent3DfEXT { + float width; + float height; + float depth; +} XrExtent3DfEXT; + +typedef struct XrPlaneDetectorBeginInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + uint32_t orientationCount; + const XrPlaneDetectorOrientationEXT* orientations; + uint32_t semanticTypeCount; + const XrPlaneDetectorSemanticTypeEXT* semanticTypes; + uint32_t maxPlanes; + float minArea; + XrPosef boundingBoxPose; + XrExtent3DfEXT boundingBoxExtent; +} XrPlaneDetectorBeginInfoEXT; + +typedef struct XrPlaneDetectorGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; +} XrPlaneDetectorGetInfoEXT; + +typedef struct XrPlaneDetectorLocationEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint64_t planeId; + XrSpaceLocationFlags locationFlags; + XrPosef pose; + XrExtent2Df extents; + XrPlaneDetectorOrientationEXT orientation; + XrPlaneDetectorSemanticTypeEXT semanticType; + uint32_t polygonBufferCount; +} XrPlaneDetectorLocationEXT; + +typedef struct XrPlaneDetectorLocationsEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t planeLocationCapacityInput; + uint32_t planeLocationCountOutput; + XrPlaneDetectorLocationEXT* planeLocations; +} XrPlaneDetectorLocationsEXT; + +typedef struct XrPlaneDetectorPolygonBufferEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector2f* vertices; +} XrPlaneDetectorPolygonBufferEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreatePlaneDetectorEXT)(XrSession session, const XrPlaneDetectorCreateInfoEXT* createInfo, XrPlaneDetectorEXT* planeDetector); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPlaneDetectorEXT)(XrPlaneDetectorEXT planeDetector); +typedef XrResult (XRAPI_PTR *PFN_xrBeginPlaneDetectionEXT)(XrPlaneDetectorEXT planeDetector, const XrPlaneDetectorBeginInfoEXT* beginInfo); +typedef XrResult (XRAPI_PTR *PFN_xrGetPlaneDetectionStateEXT)(XrPlaneDetectorEXT planeDetector, XrPlaneDetectionStateEXT* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetPlaneDetectionsEXT)(XrPlaneDetectorEXT planeDetector, const XrPlaneDetectorGetInfoEXT* info, XrPlaneDetectorLocationsEXT* locations); +typedef XrResult (XRAPI_PTR *PFN_xrGetPlanePolygonBufferEXT)(XrPlaneDetectorEXT planeDetector, uint64_t planeId, uint32_t polygonBufferIndex, XrPlaneDetectorPolygonBufferEXT* polygonBuffer); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePlaneDetectorEXT( + XrSession session, + const XrPlaneDetectorCreateInfoEXT* createInfo, + XrPlaneDetectorEXT* planeDetector); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPlaneDetectorEXT( + XrPlaneDetectorEXT planeDetector); + +XRAPI_ATTR XrResult XRAPI_CALL xrBeginPlaneDetectionEXT( + XrPlaneDetectorEXT planeDetector, + const XrPlaneDetectorBeginInfoEXT* beginInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetPlaneDetectionStateEXT( + XrPlaneDetectorEXT planeDetector, + XrPlaneDetectionStateEXT* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetPlaneDetectionsEXT( + XrPlaneDetectorEXT planeDetector, + const XrPlaneDetectorGetInfoEXT* info, + XrPlaneDetectorLocationsEXT* locations); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetPlanePolygonBufferEXT( + XrPlaneDetectorEXT planeDetector, + uint64_t planeId, + uint32_t polygonBufferIndex, + XrPlaneDetectorPolygonBufferEXT* polygonBuffer); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_OPPO_controller_interaction 1 +#define XR_OPPO_controller_interaction_SPEC_VERSION 1 +#define XR_OPPO_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_OPPO_controller_interaction" + #ifdef __cplusplus } #endif diff --git a/thirdparty/openxr/include/openxr/openxr_platform.h b/thirdparty/openxr/include/openxr/openxr_platform.h index b3aabb23c5..b0a5328f3e 100644 --- a/thirdparty/openxr/include/openxr/openxr_platform.h +++ b/thirdparty/openxr/include/openxr/openxr_platform.h @@ -2,7 +2,7 @@ #define OPENXR_PLATFORM_H_ 1 /* -** Copyright 2017-2022 The Khronos Group Inc. +** Copyright 2017-2023 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -454,9 +454,9 @@ typedef XrSwapchainImageVulkanKHR XrSwapchainImageVulkan2KHR; typedef XrGraphicsRequirementsVulkanKHR XrGraphicsRequirementsVulkan2KHR; -typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanInstanceKHR)(XrInstance instance, const XrVulkanInstanceCreateInfoKHR* createInfo, VkInstance* vulkanInstance, VkResult* vulkanResult); -typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanDeviceKHR)(XrInstance instance, const XrVulkanDeviceCreateInfoKHR* createInfo, VkDevice* vulkanDevice, VkResult* vulkanResult); -typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDevice2KHR)(XrInstance instance, const XrVulkanGraphicsDeviceGetInfoKHR* getInfo, VkPhysicalDevice* vulkanPhysicalDevice); +typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanInstanceKHR)(XrInstance instance, const XrVulkanInstanceCreateInfoKHR* createInfo, VkInstance* vulkanInstance, VkResult* vulkanResult); +typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanDeviceKHR)(XrInstance instance, const XrVulkanDeviceCreateInfoKHR* createInfo, VkDevice* vulkanDevice, VkResult* vulkanResult); +typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDevice2KHR)(XrInstance instance, const XrVulkanGraphicsDeviceGetInfoKHR* getInfo, VkPhysicalDevice* vulkanPhysicalDevice); typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsRequirements2KHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR* graphicsRequirements); #ifndef XR_NO_PROTOTYPES @@ -565,6 +565,30 @@ typedef struct XrAndroidSurfaceSwapchainCreateInfoFB { #endif /* XR_USE_PLATFORM_ANDROID */ +#ifdef XR_USE_PLATFORM_ML + +#define XR_ML_compat 1 +#define XR_ML_compat_SPEC_VERSION 1 +#define XR_ML_COMPAT_EXTENSION_NAME "XR_ML_compat" +typedef struct XrCoordinateSpaceCreateInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + MLCoordinateFrameUID cfuid; + XrPosef poseInCoordinateSpace; +} XrCoordinateSpaceCreateInfoML; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpaceFromCoordinateFrameUIDML)(XrSession session, const XrCoordinateSpaceCreateInfoML *createInfo, XrSpace* space); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpaceFromCoordinateFrameUIDML( + XrSession session, + const XrCoordinateSpaceCreateInfoML * createInfo, + XrSpace* space); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_PLATFORM_ML */ + #ifdef XR_USE_PLATFORM_WIN32 #define XR_OCULUS_audio_device_guid 1 diff --git a/thirdparty/openxr/include/openxr/openxr_platform_defines.h b/thirdparty/openxr/include/openxr/openxr_platform_defines.h index 31fa05a0c8..820b7b3e1e 100644 --- a/thirdparty/openxr/include/openxr/openxr_platform_defines.h +++ b/thirdparty/openxr/include/openxr/openxr_platform_defines.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 2017-2022, The Khronos Group Inc. +** Copyright (c) 2017-2023, The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -65,7 +65,7 @@ typedef unsigned __int64 uint64_t; #endif // !defined( XR_NO_STDINT_H ) // XR_PTR_SIZE (in bytes) -#if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)) +#if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)) #define XR_PTR_SIZE 8 #else #define XR_PTR_SIZE 4 @@ -103,6 +103,10 @@ typedef unsigned __int64 uint64_t; #endif #endif +#if !defined(XR_CPP_NULLPTR_SUPPORTED) +#define XR_CPP_NULLPTR_SUPPORTED 0 +#endif // !defined(XR_CPP_NULLPTR_SUPPORTED) + #ifdef __cplusplus } #endif diff --git a/thirdparty/openxr/include/openxr/openxr_reflection.h b/thirdparty/openxr/include/openxr/openxr_reflection.h index 1a873c1770..c53d412365 100644 --- a/thirdparty/openxr/include/openxr/openxr_reflection.h +++ b/thirdparty/openxr/include/openxr/openxr_reflection.h @@ -2,7 +2,7 @@ #define OPENXR_REFLECTION_H_ 1 /* -** Copyright (c) 2017-2022, The Khronos Group Inc. +** Copyright (c) 2017-2023, The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -116,6 +116,15 @@ XR_ENUM_STR(XrResult); _(XR_ERROR_MARKER_ID_INVALID_VARJO, -1000124001) \ _(XR_ERROR_SPATIAL_ANCHOR_NAME_NOT_FOUND_MSFT, -1000142001) \ _(XR_ERROR_SPATIAL_ANCHOR_NAME_INVALID_MSFT, -1000142002) \ + _(XR_ERROR_SPACE_MAPPING_INSUFFICIENT_FB, -1000169000) \ + _(XR_ERROR_SPACE_LOCALIZATION_FAILED_FB, -1000169001) \ + _(XR_ERROR_SPACE_NETWORK_TIMEOUT_FB, -1000169002) \ + _(XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB, -1000169003) \ + _(XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB, -1000169004) \ + _(XR_ERROR_PASSTHROUGH_COLOR_LUT_BUFFER_SIZE_MISMATCH_META, -1000266000) \ + _(XR_ERROR_HINT_ALREADY_SET_QCOM, -1000306000) \ + _(XR_ERROR_SPACE_NOT_LOCATABLE_EXT, -1000429000) \ + _(XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT, -1000429001) \ _(XR_RESULT_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrStructureType(_) \ @@ -242,6 +251,11 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT, 1000066001) \ _(XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB, 1000070000) \ _(XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB, 1000072000) \ + _(XR_TYPE_BODY_TRACKER_CREATE_INFO_FB, 1000076001) \ + _(XR_TYPE_BODY_JOINTS_LOCATE_INFO_FB, 1000076002) \ + _(XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_FB, 1000076004) \ + _(XR_TYPE_BODY_JOINT_LOCATIONS_FB, 1000076005) \ + _(XR_TYPE_BODY_SKELETON_FB, 1000076006) \ _(XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT, 1000078000) \ _(XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE, 1000079000) \ _(XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT, 1000080000) \ @@ -322,6 +336,9 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO, 1000124000) \ _(XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO, 1000124001) \ _(XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO, 1000124002) \ + _(XR_TYPE_FRAME_END_INFO_ML, 1000135000) \ + _(XR_TYPE_GLOBAL_DIMMER_FRAME_END_INFO_ML, 1000136000) \ + _(XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML, 1000137000) \ _(XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT, 1000142000) \ _(XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT, 1000142001) \ _(XR_TYPE_SPACE_QUERY_INFO_FB, 1000156001) \ @@ -339,19 +356,64 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB, 1000161000) \ _(XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB, 1000162000) \ _(XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB, 1000163000) \ + _(XR_TYPE_SPACE_SHARE_INFO_FB, 1000169001) \ + _(XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB, 1000169002) \ _(XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB, 1000171000) \ _(XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB, 1000171001) \ + _(XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB, 1000173001) \ _(XR_TYPE_SEMANTIC_LABELS_FB, 1000175000) \ _(XR_TYPE_ROOM_LAYOUT_FB, 1000175001) \ _(XR_TYPE_BOUNDARY_2D_FB, 1000175002) \ + _(XR_TYPE_SEMANTIC_LABELS_SUPPORT_INFO_FB, 1000175010) \ _(XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE, 1000196000) \ + _(XR_TYPE_EVENT_DATA_SCENE_CAPTURE_COMPLETE_FB, 1000198001) \ + _(XR_TYPE_SCENE_CAPTURE_REQUEST_INFO_FB, 1000198050) \ _(XR_TYPE_SPACE_CONTAINER_FB, 1000199000) \ + _(XR_TYPE_FOVEATION_EYE_TRACKED_PROFILE_CREATE_INFO_META, 1000200000) \ + _(XR_TYPE_FOVEATION_EYE_TRACKED_STATE_META, 1000200001) \ + _(XR_TYPE_SYSTEM_FOVEATION_EYE_TRACKED_PROPERTIES_META, 1000200002) \ + _(XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_FB, 1000201004) \ + _(XR_TYPE_FACE_TRACKER_CREATE_INFO_FB, 1000201005) \ + _(XR_TYPE_FACE_EXPRESSION_INFO_FB, 1000201002) \ + _(XR_TYPE_FACE_EXPRESSION_WEIGHTS_FB, 1000201006) \ + _(XR_TYPE_EYE_TRACKER_CREATE_INFO_FB, 1000202001) \ + _(XR_TYPE_EYE_GAZES_INFO_FB, 1000202002) \ + _(XR_TYPE_EYE_GAZES_FB, 1000202003) \ + _(XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_FB, 1000202004) \ _(XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB, 1000203002) \ _(XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB, 1000204000) \ + _(XR_TYPE_HAPTIC_PCM_VIBRATION_FB, 1000209001) \ + _(XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB, 1000209002) \ + _(XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_FB, 1000212000) \ + _(XR_TYPE_LOCAL_DIMMING_FRAME_END_INFO_META, 1000216000) \ + _(XR_TYPE_SYSTEM_VIRTUAL_KEYBOARD_PROPERTIES_META, 1000219001) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_CREATE_INFO_META, 1000219002) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_SPACE_CREATE_INFO_META, 1000219003) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_LOCATION_INFO_META, 1000219004) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_MODEL_VISIBILITY_SET_INFO_META, 1000219005) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_ANIMATION_STATE_META, 1000219006) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_MODEL_ANIMATION_STATES_META, 1000219007) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_TEXTURE_DATA_META, 1000219009) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_INPUT_INFO_META, 1000219010) \ + _(XR_TYPE_VIRTUAL_KEYBOARD_TEXT_CONTEXT_CHANGE_INFO_META, 1000219011) \ + _(XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_COMMIT_TEXT_META, 1000219014) \ + _(XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_BACKSPACE_META, 1000219015) \ + _(XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_ENTER_META, 1000219016) \ + _(XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_SHOWN_META, 1000219017) \ + _(XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_HIDDEN_META, 1000219018) \ + _(XR_TYPE_EXTERNAL_CAMERA_OCULUS, 1000226000) \ _(XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META, 1000227000) \ _(XR_TYPE_PERFORMANCE_METRICS_STATE_META, 1000232001) \ _(XR_TYPE_PERFORMANCE_METRICS_COUNTER_META, 1000232002) \ + _(XR_TYPE_SPACE_LIST_SAVE_INFO_FB, 1000238000) \ + _(XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB, 1000238001) \ + _(XR_TYPE_SPACE_USER_CREATE_INFO_FB, 1000241001) \ _(XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META, 1000245000) \ + _(XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META, 1000266000) \ + _(XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META, 1000266001) \ + _(XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META, 1000266002) \ + _(XR_TYPE_PASSTHROUGH_COLOR_MAP_LUT_META, 1000266100) \ + _(XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META, 1000266101) \ _(XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC, 1000317001) \ _(XR_TYPE_PASSTHROUGH_COLOR_HTC, 1000317002) \ _(XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC, 1000317003) \ @@ -360,6 +422,17 @@ XR_ENUM_STR(XrResult); _(XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC, 1000318001) \ _(XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC, 1000318002) \ _(XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT, 1000373000) \ + _(XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX, 1000375000) \ + _(XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX, 1000375001) \ + _(XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT, 1000428000) \ + _(XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT, 1000428001) \ + _(XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT, 1000429001) \ + _(XR_TYPE_PLANE_DETECTOR_BEGIN_INFO_EXT, 1000429002) \ + _(XR_TYPE_PLANE_DETECTOR_GET_INFO_EXT, 1000429003) \ + _(XR_TYPE_PLANE_DETECTOR_LOCATIONS_EXT, 1000429004) \ + _(XR_TYPE_PLANE_DETECTOR_LOCATION_EXT, 1000429005) \ + _(XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT, 1000429006) \ + _(XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT, 1000429007) \ _(XR_STRUCTURE_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrFormFactor(_) \ @@ -386,6 +459,7 @@ XR_ENUM_STR(XrResult); _(XR_REFERENCE_SPACE_TYPE_STAGE, 3) \ _(XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT, 1000038000) \ _(XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO, 1000121000) \ + _(XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT, 1000426000) \ _(XR_REFERENCE_SPACE_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrActionType(_) \ @@ -426,6 +500,7 @@ XR_ENUM_STR(XrResult); _(XR_OBJECT_TYPE_SPATIAL_ANCHOR_MSFT, 1000039000) \ _(XR_OBJECT_TYPE_SPATIAL_GRAPH_NODE_BINDING_MSFT, 1000049000) \ _(XR_OBJECT_TYPE_HAND_TRACKER_EXT, 1000051000) \ + _(XR_OBJECT_TYPE_BODY_TRACKER_FB, 1000076000) \ _(XR_OBJECT_TYPE_SCENE_OBSERVER_MSFT, 1000097000) \ _(XR_OBJECT_TYPE_SCENE_MSFT, 1000097001) \ _(XR_OBJECT_TYPE_FACIAL_TRACKER_HTC, 1000104000) \ @@ -435,7 +510,13 @@ XR_ENUM_STR(XrResult); _(XR_OBJECT_TYPE_PASSTHROUGH_LAYER_FB, 1000118002) \ _(XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB, 1000118004) \ _(XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT, 1000142000) \ + _(XR_OBJECT_TYPE_FACE_TRACKER_FB, 1000201000) \ + _(XR_OBJECT_TYPE_EYE_TRACKER_FB, 1000202000) \ + _(XR_OBJECT_TYPE_VIRTUAL_KEYBOARD_META, 1000219000) \ + _(XR_OBJECT_TYPE_SPACE_USER_FB, 1000241000) \ + _(XR_OBJECT_TYPE_PASSTHROUGH_COLOR_LUT_META, 1000266000) \ _(XR_OBJECT_TYPE_PASSTHROUGH_HTC, 1000317000) \ + _(XR_OBJECT_TYPE_PLANE_DETECTOR_EXT, 1000429000) \ _(XR_OBJECT_TYPE_MAX_ENUM, 0x7FFFFFFF) #define XR_LIST_ENUM_XrAndroidThreadTypeKHR(_) \ @@ -540,6 +621,85 @@ XR_ENUM_STR(XrResult); _(XR_REPROJECTION_MODE_ORIENTATION_ONLY_MSFT, 4) \ _(XR_REPROJECTION_MODE_MAX_ENUM_MSFT, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrBodyJointFB(_) \ + _(XR_BODY_JOINT_ROOT_FB, 0) \ + _(XR_BODY_JOINT_HIPS_FB, 1) \ + _(XR_BODY_JOINT_SPINE_LOWER_FB, 2) \ + _(XR_BODY_JOINT_SPINE_MIDDLE_FB, 3) \ + _(XR_BODY_JOINT_SPINE_UPPER_FB, 4) \ + _(XR_BODY_JOINT_CHEST_FB, 5) \ + _(XR_BODY_JOINT_NECK_FB, 6) \ + _(XR_BODY_JOINT_HEAD_FB, 7) \ + _(XR_BODY_JOINT_LEFT_SHOULDER_FB, 8) \ + _(XR_BODY_JOINT_LEFT_SCAPULA_FB, 9) \ + _(XR_BODY_JOINT_LEFT_ARM_UPPER_FB, 10) \ + _(XR_BODY_JOINT_LEFT_ARM_LOWER_FB, 11) \ + _(XR_BODY_JOINT_LEFT_HAND_WRIST_TWIST_FB, 12) \ + _(XR_BODY_JOINT_RIGHT_SHOULDER_FB, 13) \ + _(XR_BODY_JOINT_RIGHT_SCAPULA_FB, 14) \ + _(XR_BODY_JOINT_RIGHT_ARM_UPPER_FB, 15) \ + _(XR_BODY_JOINT_RIGHT_ARM_LOWER_FB, 16) \ + _(XR_BODY_JOINT_RIGHT_HAND_WRIST_TWIST_FB, 17) \ + _(XR_BODY_JOINT_LEFT_HAND_PALM_FB, 18) \ + _(XR_BODY_JOINT_LEFT_HAND_WRIST_FB, 19) \ + _(XR_BODY_JOINT_LEFT_HAND_THUMB_METACARPAL_FB, 20) \ + _(XR_BODY_JOINT_LEFT_HAND_THUMB_PROXIMAL_FB, 21) \ + _(XR_BODY_JOINT_LEFT_HAND_THUMB_DISTAL_FB, 22) \ + _(XR_BODY_JOINT_LEFT_HAND_THUMB_TIP_FB, 23) \ + _(XR_BODY_JOINT_LEFT_HAND_INDEX_METACARPAL_FB, 24) \ + _(XR_BODY_JOINT_LEFT_HAND_INDEX_PROXIMAL_FB, 25) \ + _(XR_BODY_JOINT_LEFT_HAND_INDEX_INTERMEDIATE_FB, 26) \ + _(XR_BODY_JOINT_LEFT_HAND_INDEX_DISTAL_FB, 27) \ + _(XR_BODY_JOINT_LEFT_HAND_INDEX_TIP_FB, 28) \ + _(XR_BODY_JOINT_LEFT_HAND_MIDDLE_METACARPAL_FB, 29) \ + _(XR_BODY_JOINT_LEFT_HAND_MIDDLE_PROXIMAL_FB, 30) \ + _(XR_BODY_JOINT_LEFT_HAND_MIDDLE_INTERMEDIATE_FB, 31) \ + _(XR_BODY_JOINT_LEFT_HAND_MIDDLE_DISTAL_FB, 32) \ + _(XR_BODY_JOINT_LEFT_HAND_MIDDLE_TIP_FB, 33) \ + _(XR_BODY_JOINT_LEFT_HAND_RING_METACARPAL_FB, 34) \ + _(XR_BODY_JOINT_LEFT_HAND_RING_PROXIMAL_FB, 35) \ + _(XR_BODY_JOINT_LEFT_HAND_RING_INTERMEDIATE_FB, 36) \ + _(XR_BODY_JOINT_LEFT_HAND_RING_DISTAL_FB, 37) \ + _(XR_BODY_JOINT_LEFT_HAND_RING_TIP_FB, 38) \ + _(XR_BODY_JOINT_LEFT_HAND_LITTLE_METACARPAL_FB, 39) \ + _(XR_BODY_JOINT_LEFT_HAND_LITTLE_PROXIMAL_FB, 40) \ + _(XR_BODY_JOINT_LEFT_HAND_LITTLE_INTERMEDIATE_FB, 41) \ + _(XR_BODY_JOINT_LEFT_HAND_LITTLE_DISTAL_FB, 42) \ + _(XR_BODY_JOINT_LEFT_HAND_LITTLE_TIP_FB, 43) \ + _(XR_BODY_JOINT_RIGHT_HAND_PALM_FB, 44) \ + _(XR_BODY_JOINT_RIGHT_HAND_WRIST_FB, 45) \ + _(XR_BODY_JOINT_RIGHT_HAND_THUMB_METACARPAL_FB, 46) \ + _(XR_BODY_JOINT_RIGHT_HAND_THUMB_PROXIMAL_FB, 47) \ + _(XR_BODY_JOINT_RIGHT_HAND_THUMB_DISTAL_FB, 48) \ + _(XR_BODY_JOINT_RIGHT_HAND_THUMB_TIP_FB, 49) \ + _(XR_BODY_JOINT_RIGHT_HAND_INDEX_METACARPAL_FB, 50) \ + _(XR_BODY_JOINT_RIGHT_HAND_INDEX_PROXIMAL_FB, 51) \ + _(XR_BODY_JOINT_RIGHT_HAND_INDEX_INTERMEDIATE_FB, 52) \ + _(XR_BODY_JOINT_RIGHT_HAND_INDEX_DISTAL_FB, 53) \ + _(XR_BODY_JOINT_RIGHT_HAND_INDEX_TIP_FB, 54) \ + _(XR_BODY_JOINT_RIGHT_HAND_MIDDLE_METACARPAL_FB, 55) \ + _(XR_BODY_JOINT_RIGHT_HAND_MIDDLE_PROXIMAL_FB, 56) \ + _(XR_BODY_JOINT_RIGHT_HAND_MIDDLE_INTERMEDIATE_FB, 57) \ + _(XR_BODY_JOINT_RIGHT_HAND_MIDDLE_DISTAL_FB, 58) \ + _(XR_BODY_JOINT_RIGHT_HAND_MIDDLE_TIP_FB, 59) \ + _(XR_BODY_JOINT_RIGHT_HAND_RING_METACARPAL_FB, 60) \ + _(XR_BODY_JOINT_RIGHT_HAND_RING_PROXIMAL_FB, 61) \ + _(XR_BODY_JOINT_RIGHT_HAND_RING_INTERMEDIATE_FB, 62) \ + _(XR_BODY_JOINT_RIGHT_HAND_RING_DISTAL_FB, 63) \ + _(XR_BODY_JOINT_RIGHT_HAND_RING_TIP_FB, 64) \ + _(XR_BODY_JOINT_RIGHT_HAND_LITTLE_METACARPAL_FB, 65) \ + _(XR_BODY_JOINT_RIGHT_HAND_LITTLE_PROXIMAL_FB, 66) \ + _(XR_BODY_JOINT_RIGHT_HAND_LITTLE_INTERMEDIATE_FB, 67) \ + _(XR_BODY_JOINT_RIGHT_HAND_LITTLE_DISTAL_FB, 68) \ + _(XR_BODY_JOINT_RIGHT_HAND_LITTLE_TIP_FB, 69) \ + _(XR_BODY_JOINT_COUNT_FB, 70) \ + _(XR_BODY_JOINT_NONE_FB, -1) \ + _(XR_BODY_JOINT_MAX_ENUM_FB, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrBodyJointSetFB(_) \ + _(XR_BODY_JOINT_SET_DEFAULT_FB, 0) \ + _(XR_BODY_JOINT_SET_MAX_ENUM_FB, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrHandJointsMotionRangeEXT(_) \ _(XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT, 1) \ _(XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT, 2) \ @@ -674,6 +834,7 @@ XR_ENUM_STR(XrResult); #define XR_LIST_ENUM_XrSpaceComponentTypeFB(_) \ _(XR_SPACE_COMPONENT_TYPE_LOCATABLE_FB, 0) \ _(XR_SPACE_COMPONENT_TYPE_STORABLE_FB, 1) \ + _(XR_SPACE_COMPONENT_TYPE_SHARABLE_FB, 2) \ _(XR_SPACE_COMPONENT_TYPE_BOUNDED_2D_FB, 3) \ _(XR_SPACE_COMPONENT_TYPE_BOUNDED_3D_FB, 4) \ _(XR_SPACE_COMPONENT_TYPE_SEMANTIC_LABELS_FB, 5) \ @@ -743,6 +904,7 @@ XR_ENUM_STR(XrResult); #define XR_LIST_ENUM_XrSpaceStorageLocationFB(_) \ _(XR_SPACE_STORAGE_LOCATION_INVALID_FB, 0) \ _(XR_SPACE_STORAGE_LOCATION_LOCAL_FB, 1) \ + _(XR_SPACE_STORAGE_LOCATION_CLOUD_FB, 2) \ _(XR_SPACE_STORAGE_LOCATION_MAX_ENUM_FB, 0x7FFFFFFF) #define XR_LIST_ENUM_XrSpacePersistenceModeFB(_) \ @@ -750,6 +912,129 @@ XR_ENUM_STR(XrResult); _(XR_SPACE_PERSISTENCE_MODE_INDEFINITE_FB, 1) \ _(XR_SPACE_PERSISTENCE_MODE_MAX_ENUM_FB, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrFaceExpressionFB(_) \ + _(XR_FACE_EXPRESSION_BROW_LOWERER_L_FB, 0) \ + _(XR_FACE_EXPRESSION_BROW_LOWERER_R_FB, 1) \ + _(XR_FACE_EXPRESSION_CHEEK_PUFF_L_FB, 2) \ + _(XR_FACE_EXPRESSION_CHEEK_PUFF_R_FB, 3) \ + _(XR_FACE_EXPRESSION_CHEEK_RAISER_L_FB, 4) \ + _(XR_FACE_EXPRESSION_CHEEK_RAISER_R_FB, 5) \ + _(XR_FACE_EXPRESSION_CHEEK_SUCK_L_FB, 6) \ + _(XR_FACE_EXPRESSION_CHEEK_SUCK_R_FB, 7) \ + _(XR_FACE_EXPRESSION_CHIN_RAISER_B_FB, 8) \ + _(XR_FACE_EXPRESSION_CHIN_RAISER_T_FB, 9) \ + _(XR_FACE_EXPRESSION_DIMPLER_L_FB, 10) \ + _(XR_FACE_EXPRESSION_DIMPLER_R_FB, 11) \ + _(XR_FACE_EXPRESSION_EYES_CLOSED_L_FB, 12) \ + _(XR_FACE_EXPRESSION_EYES_CLOSED_R_FB, 13) \ + _(XR_FACE_EXPRESSION_EYES_LOOK_DOWN_L_FB, 14) \ + _(XR_FACE_EXPRESSION_EYES_LOOK_DOWN_R_FB, 15) \ + _(XR_FACE_EXPRESSION_EYES_LOOK_LEFT_L_FB, 16) \ + _(XR_FACE_EXPRESSION_EYES_LOOK_LEFT_R_FB, 17) \ + _(XR_FACE_EXPRESSION_EYES_LOOK_RIGHT_L_FB, 18) \ + _(XR_FACE_EXPRESSION_EYES_LOOK_RIGHT_R_FB, 19) \ + _(XR_FACE_EXPRESSION_EYES_LOOK_UP_L_FB, 20) \ + _(XR_FACE_EXPRESSION_EYES_LOOK_UP_R_FB, 21) \ + _(XR_FACE_EXPRESSION_INNER_BROW_RAISER_L_FB, 22) \ + _(XR_FACE_EXPRESSION_INNER_BROW_RAISER_R_FB, 23) \ + _(XR_FACE_EXPRESSION_JAW_DROP_FB, 24) \ + _(XR_FACE_EXPRESSION_JAW_SIDEWAYS_LEFT_FB, 25) \ + _(XR_FACE_EXPRESSION_JAW_SIDEWAYS_RIGHT_FB, 26) \ + _(XR_FACE_EXPRESSION_JAW_THRUST_FB, 27) \ + _(XR_FACE_EXPRESSION_LID_TIGHTENER_L_FB, 28) \ + _(XR_FACE_EXPRESSION_LID_TIGHTENER_R_FB, 29) \ + _(XR_FACE_EXPRESSION_LIP_CORNER_DEPRESSOR_L_FB, 30) \ + _(XR_FACE_EXPRESSION_LIP_CORNER_DEPRESSOR_R_FB, 31) \ + _(XR_FACE_EXPRESSION_LIP_CORNER_PULLER_L_FB, 32) \ + _(XR_FACE_EXPRESSION_LIP_CORNER_PULLER_R_FB, 33) \ + _(XR_FACE_EXPRESSION_LIP_FUNNELER_LB_FB, 34) \ + _(XR_FACE_EXPRESSION_LIP_FUNNELER_LT_FB, 35) \ + _(XR_FACE_EXPRESSION_LIP_FUNNELER_RB_FB, 36) \ + _(XR_FACE_EXPRESSION_LIP_FUNNELER_RT_FB, 37) \ + _(XR_FACE_EXPRESSION_LIP_PRESSOR_L_FB, 38) \ + _(XR_FACE_EXPRESSION_LIP_PRESSOR_R_FB, 39) \ + _(XR_FACE_EXPRESSION_LIP_PUCKER_L_FB, 40) \ + _(XR_FACE_EXPRESSION_LIP_PUCKER_R_FB, 41) \ + _(XR_FACE_EXPRESSION_LIP_STRETCHER_L_FB, 42) \ + _(XR_FACE_EXPRESSION_LIP_STRETCHER_R_FB, 43) \ + _(XR_FACE_EXPRESSION_LIP_SUCK_LB_FB, 44) \ + _(XR_FACE_EXPRESSION_LIP_SUCK_LT_FB, 45) \ + _(XR_FACE_EXPRESSION_LIP_SUCK_RB_FB, 46) \ + _(XR_FACE_EXPRESSION_LIP_SUCK_RT_FB, 47) \ + _(XR_FACE_EXPRESSION_LIP_TIGHTENER_L_FB, 48) \ + _(XR_FACE_EXPRESSION_LIP_TIGHTENER_R_FB, 49) \ + _(XR_FACE_EXPRESSION_LIPS_TOWARD_FB, 50) \ + _(XR_FACE_EXPRESSION_LOWER_LIP_DEPRESSOR_L_FB, 51) \ + _(XR_FACE_EXPRESSION_LOWER_LIP_DEPRESSOR_R_FB, 52) \ + _(XR_FACE_EXPRESSION_MOUTH_LEFT_FB, 53) \ + _(XR_FACE_EXPRESSION_MOUTH_RIGHT_FB, 54) \ + _(XR_FACE_EXPRESSION_NOSE_WRINKLER_L_FB, 55) \ + _(XR_FACE_EXPRESSION_NOSE_WRINKLER_R_FB, 56) \ + _(XR_FACE_EXPRESSION_OUTER_BROW_RAISER_L_FB, 57) \ + _(XR_FACE_EXPRESSION_OUTER_BROW_RAISER_R_FB, 58) \ + _(XR_FACE_EXPRESSION_UPPER_LID_RAISER_L_FB, 59) \ + _(XR_FACE_EXPRESSION_UPPER_LID_RAISER_R_FB, 60) \ + _(XR_FACE_EXPRESSION_UPPER_LIP_RAISER_L_FB, 61) \ + _(XR_FACE_EXPRESSION_UPPER_LIP_RAISER_R_FB, 62) \ + _(XR_FACE_EXPRESSION_COUNT_FB, 63) \ + _(XR_FACE_EXPRESSION_MAX_ENUM_FB, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFaceExpressionSetFB(_) \ + _(XR_FACE_EXPRESSION_SET_DEFAULT_FB, 0) \ + _(XR_FACE_EXPRESSION_SET_MAX_ENUM_FB, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrFaceConfidenceFB(_) \ + _(XR_FACE_CONFIDENCE_LOWER_FACE_FB, 0) \ + _(XR_FACE_CONFIDENCE_UPPER_FACE_FB, 1) \ + _(XR_FACE_CONFIDENCE_COUNT_FB, 2) \ + _(XR_FACE_CONFIDENCE_MAX_ENUM_FB, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrEyePositionFB(_) \ + _(XR_EYE_POSITION_LEFT_FB, 0) \ + _(XR_EYE_POSITION_RIGHT_FB, 1) \ + _(XR_EYE_POSITION_COUNT_FB, 2) \ + _(XR_EYE_POSITION_MAX_ENUM_FB, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrCompareOpFB(_) \ + _(XR_COMPARE_OP_NEVER_FB, 0) \ + _(XR_COMPARE_OP_LESS_FB, 1) \ + _(XR_COMPARE_OP_EQUAL_FB, 2) \ + _(XR_COMPARE_OP_LESS_OR_EQUAL_FB, 3) \ + _(XR_COMPARE_OP_GREATER_FB, 4) \ + _(XR_COMPARE_OP_NOT_EQUAL_FB, 5) \ + _(XR_COMPARE_OP_GREATER_OR_EQUAL_FB, 6) \ + _(XR_COMPARE_OP_ALWAYS_FB, 7) \ + _(XR_COMPARE_OPFB_MAX_ENUM_FB, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrLocalDimmingModeMETA(_) \ + _(XR_LOCAL_DIMMING_MODE_OFF_META, 0) \ + _(XR_LOCAL_DIMMING_MODE_ON_META, 1) \ + _(XR_LOCAL_DIMMING_MODE_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrVirtualKeyboardLocationTypeMETA(_) \ + _(XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_CUSTOM_META, 0) \ + _(XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_FAR_META, 1) \ + _(XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_DIRECT_META, 2) \ + _(XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrVirtualKeyboardInputSourceMETA(_) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_RAY_LEFT_META, 1) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_RAY_RIGHT_META, 2) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_RAY_LEFT_META, 3) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_RAY_RIGHT_META, 4) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_DIRECT_LEFT_META, 5) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_DIRECT_RIGHT_META, 6) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_DIRECT_INDEX_TIP_LEFT_META, 7) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_DIRECT_INDEX_TIP_RIGHT_META, 8) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrExternalCameraAttachedToDeviceOCULUS(_) \ + _(XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_NONE_OCULUS, 0) \ + _(XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_HMD_OCULUS, 1) \ + _(XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_LTOUCH_OCULUS, 2) \ + _(XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_RTOUCH_OCULUS, 3) \ + _(XR_EXTERNAL_CAMERA_ATTACHED_TODEVICE_MAX_ENUM_OCULUS, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrPerformanceMetricsCounterUnitMETA(_) \ _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_GENERIC_META, 0) \ _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_PERCENTAGE_META, 1) \ @@ -758,6 +1043,23 @@ XR_ENUM_STR(XrResult); _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_HERTZ_META, 4) \ _(XR_PERFORMANCE_METRICS_COUNTER_UNIT_MAX_ENUM_META, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrPassthroughColorLutChannelsMETA(_) \ + _(XR_PASSTHROUGH_COLOR_LUT_CHANNELS_RGB_META, 1) \ + _(XR_PASSTHROUGH_COLOR_LUT_CHANNELS_RGBA_META, 2) \ + _(XR_PASSTHROUGH_COLOR_LUT_CHANNELS_MAX_ENUM_META, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrTrackingOptimizationSettingsDomainQCOM(_) \ + _(XR_TRACKING_OPTIMIZATION_SETTINGS_DOMAIN_ALL_QCOM, 1) \ + _(XR_TRACKING_OPTIMIZATION_SETTINGS_DOMAIN_MAX_ENUM_QCOM, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrTrackingOptimizationSettingsHintQCOM(_) \ + _(XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_NONE_QCOM, 0) \ + _(XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_LONG_RANGE_PRIORIZATION_QCOM, 1) \ + _(XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_CLOSE_RANGE_PRIORIZATION_QCOM, 2) \ + _(XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_LOW_POWER_PRIORIZATION_QCOM, 3) \ + _(XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_HIGH_POWER_PRIORIZATION_QCOM, 4) \ + _(XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_MAX_ENUM_QCOM, 0x7FFFFFFF) + #define XR_LIST_ENUM_XrPassthroughFormHTC(_) \ _(XR_PASSTHROUGH_FORM_PLANAR_HTC, 0) \ _(XR_PASSTHROUGH_FORM_PROJECTED_HTC, 1) \ @@ -777,6 +1079,42 @@ XR_ENUM_STR(XrResult); _(XR_FOVEATION_LEVEL_HIGH_HTC, 3) \ _(XR_FOVEATION_LEVEL_MAX_ENUM_HTC, 0x7FFFFFFF) +#define XR_LIST_ENUM_XrForceFeedbackCurlLocationMNDX(_) \ + _(XR_FORCE_FEEDBACK_CURL_LOCATION_THUMB_CURL_MNDX, 0) \ + _(XR_FORCE_FEEDBACK_CURL_LOCATION_INDEX_CURL_MNDX, 1) \ + _(XR_FORCE_FEEDBACK_CURL_LOCATION_MIDDLE_CURL_MNDX, 2) \ + _(XR_FORCE_FEEDBACK_CURL_LOCATION_RING_CURL_MNDX, 3) \ + _(XR_FORCE_FEEDBACK_CURL_LOCATION_LITTLE_CURL_MNDX, 4) \ + _(XR_FORCE_FEEDBACK_CURL_LOCATION_MAX_ENUM_MNDX, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrHandTrackingDataSourceEXT(_) \ + _(XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT, 1) \ + _(XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT, 2) \ + _(XR_HAND_TRACKING_DATA_SOURCE_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPlaneDetectorOrientationEXT(_) \ + _(XR_PLANE_DETECTOR_ORIENTATION_HORIZONTAL_UPWARD_EXT, 0) \ + _(XR_PLANE_DETECTOR_ORIENTATION_HORIZONTAL_DOWNWARD_EXT, 1) \ + _(XR_PLANE_DETECTOR_ORIENTATION_VERTICAL_EXT, 2) \ + _(XR_PLANE_DETECTOR_ORIENTATION_ARBITRARY_EXT, 3) \ + _(XR_PLANE_DETECTOR_ORIENTATION_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPlaneDetectorSemanticTypeEXT(_) \ + _(XR_PLANE_DETECTOR_SEMANTIC_TYPE_UNDEFINED_EXT, 0) \ + _(XR_PLANE_DETECTOR_SEMANTIC_TYPE_CEILING_EXT, 1) \ + _(XR_PLANE_DETECTOR_SEMANTIC_TYPE_FLOOR_EXT, 2) \ + _(XR_PLANE_DETECTOR_SEMANTIC_TYPE_WALL_EXT, 3) \ + _(XR_PLANE_DETECTOR_SEMANTIC_TYPE_PLATFORM_EXT, 4) \ + _(XR_PLANE_DETECTOR_SEMANTIC_TYPE_MAX_ENUM_EXT, 0x7FFFFFFF) + +#define XR_LIST_ENUM_XrPlaneDetectionStateEXT(_) \ + _(XR_PLANE_DETECTION_STATE_NONE_EXT, 0) \ + _(XR_PLANE_DETECTION_STATE_PENDING_EXT, 1) \ + _(XR_PLANE_DETECTION_STATE_DONE_EXT, 2) \ + _(XR_PLANE_DETECTION_STATE_ERROR_EXT, 3) \ + _(XR_PLANE_DETECTION_STATE_FATAL_EXT, 4) \ + _(XR_PLANE_DETECTION_STATE_MAX_ENUM_EXT, 0x7FFFFFFF) + #define XR_LIST_BITS_XrInstanceCreateFlags(_) #define XR_LIST_BITS_XrSessionCreateFlags(_) @@ -903,18 +1241,44 @@ XR_ENUM_STR(XrResult); _(XR_RENDER_MODEL_SUPPORTS_GLTF_2_0_SUBSET_1_BIT_FB, 0x00000001) \ _(XR_RENDER_MODEL_SUPPORTS_GLTF_2_0_SUBSET_2_BIT_FB, 0x00000002) \ +#define XR_LIST_BITS_XrFrameEndInfoFlagsML(_) \ + _(XR_FRAME_END_INFO_PROTECTED_BIT_ML, 0x00000001) \ + _(XR_FRAME_END_INFO_VIGNETTE_BIT_ML, 0x00000002) \ + +#define XR_LIST_BITS_XrGlobalDimmerFrameEndInfoFlagsML(_) \ + _(XR_GLOBAL_DIMMER_FRAME_END_INFO_ENABLED_BIT_ML, 0x00000001) \ + #define XR_LIST_BITS_XrCompositionLayerSpaceWarpInfoFlagsFB(_) \ _(XR_COMPOSITION_LAYER_SPACE_WARP_INFO_FRAME_SKIP_BIT_FB, 0x00000001) \ +#define XR_LIST_BITS_XrSemanticLabelsSupportFlagsFB(_) \ + _(XR_SEMANTIC_LABELS_SUPPORT_MULTIPLE_SEMANTIC_LABELS_BIT_FB, 0x00000001) \ + _(XR_SEMANTIC_LABELS_SUPPORT_ACCEPT_DESK_TO_TABLE_MIGRATION_BIT_FB, 0x00000002) \ + #define XR_LIST_BITS_XrDigitalLensControlFlagsALMALENCE(_) \ _(XR_DIGITAL_LENS_CONTROL_PROCESSING_DISABLE_BIT_ALMALENCE, 0x00000001) \ +#define XR_LIST_BITS_XrFoveationEyeTrackedProfileCreateFlagsMETA(_) + +#define XR_LIST_BITS_XrFoveationEyeTrackedStateFlagsMETA(_) \ + _(XR_FOVEATION_EYE_TRACKED_STATE_VALID_BIT_META, 0x00000001) \ + #define XR_LIST_BITS_XrCompositionLayerSettingsFlagsFB(_) \ _(XR_COMPOSITION_LAYER_SETTINGS_NORMAL_SUPER_SAMPLING_BIT_FB, 0x00000001) \ _(XR_COMPOSITION_LAYER_SETTINGS_QUALITY_SUPER_SAMPLING_BIT_FB, 0x00000002) \ _(XR_COMPOSITION_LAYER_SETTINGS_NORMAL_SHARPENING_BIT_FB, 0x00000004) \ _(XR_COMPOSITION_LAYER_SETTINGS_QUALITY_SHARPENING_BIT_FB, 0x00000008) \ +#define XR_LIST_BITS_XrVirtualKeyboardInputStateFlagsMETA(_) \ + _(XR_VIRTUAL_KEYBOARD_INPUT_STATE_PRESSED_BIT_META, 0x00000001) \ + +#define XR_LIST_BITS_XrExternalCameraStatusFlagsOCULUS(_) \ + _(XR_EXTERNAL_CAMERA_STATUS_CONNECTED_BIT_OCULUS, 0x00000001) \ + _(XR_EXTERNAL_CAMERA_STATUS_CALIBRATING_BIT_OCULUS, 0x00000002) \ + _(XR_EXTERNAL_CAMERA_STATUS_CALIBRATION_FAILED_BIT_OCULUS, 0x00000004) \ + _(XR_EXTERNAL_CAMERA_STATUS_CALIBRATED_BIT_OCULUS, 0x00000008) \ + _(XR_EXTERNAL_CAMERA_STATUS_CAPTURING_BIT_OCULUS, 0x00000010) \ + #define XR_LIST_BITS_XrPerformanceMetricsCounterFlagsMETA(_) \ _(XR_PERFORMANCE_METRICS_COUNTER_ANY_VALUE_VALID_BIT_META, 0x00000001) \ _(XR_PERFORMANCE_METRICS_COUNTER_UINT_VALUE_VALID_BIT_META, 0x00000002) \ @@ -925,6 +1289,18 @@ XR_ENUM_STR(XrResult); _(XR_FOVEATION_DYNAMIC_CLEAR_FOV_ENABLED_BIT_HTC, 0x00000002) \ _(XR_FOVEATION_DYNAMIC_FOCAL_CENTER_OFFSET_ENABLED_BIT_HTC, 0x00000004) \ +#define XR_LIST_BITS_XrPlaneDetectionCapabilityFlagsEXT(_) \ + _(XR_PLANE_DETECTION_CAPABILITY_PLANE_DETECTION_BIT_EXT, 0x00000001) \ + _(XR_PLANE_DETECTION_CAPABILITY_PLANE_HOLES_BIT_EXT, 0x00000002) \ + _(XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_CEILING_BIT_EXT, 0x00000004) \ + _(XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_FLOOR_BIT_EXT, 0x00000008) \ + _(XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_WALL_BIT_EXT, 0x00000010) \ + _(XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_PLATFORM_BIT_EXT, 0x00000020) \ + _(XR_PLANE_DETECTION_CAPABILITY_ORIENTATION_BIT_EXT, 0x00000040) \ + +#define XR_LIST_BITS_XrPlaneDetectorFlagsEXT(_) \ + _(XR_PLANE_DETECTOR_ENABLE_CONTOUR_BIT_EXT, 0x00000001) \ + /// Calls your macro with the name of each member of XrApiLayerProperties, in order. #define XR_LIST_STRUCT_XrApiLayerProperties(_) \ _(type) \ @@ -2095,6 +2471,54 @@ XR_ENUM_STR(XrResult); _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrBodyJointLocationFB, in order. +#define XR_LIST_STRUCT_XrBodyJointLocationFB(_) \ + _(locationFlags) \ + _(pose) \ + +/// Calls your macro with the name of each member of XrSystemBodyTrackingPropertiesFB, in order. +#define XR_LIST_STRUCT_XrSystemBodyTrackingPropertiesFB(_) \ + _(type) \ + _(next) \ + _(supportsBodyTracking) \ + +/// Calls your macro with the name of each member of XrBodyTrackerCreateInfoFB, in order. +#define XR_LIST_STRUCT_XrBodyTrackerCreateInfoFB(_) \ + _(type) \ + _(next) \ + _(bodyJointSet) \ + +/// Calls your macro with the name of each member of XrBodySkeletonJointFB, in order. +#define XR_LIST_STRUCT_XrBodySkeletonJointFB(_) \ + _(joint) \ + _(parentJoint) \ + _(pose) \ + +/// Calls your macro with the name of each member of XrBodySkeletonFB, in order. +#define XR_LIST_STRUCT_XrBodySkeletonFB(_) \ + _(type) \ + _(next) \ + _(jointCount) \ + _(joints) \ + +/// Calls your macro with the name of each member of XrBodyJointsLocateInfoFB, in order. +#define XR_LIST_STRUCT_XrBodyJointsLocateInfoFB(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + +/// Calls your macro with the name of each member of XrBodyJointLocationsFB, in order. +#define XR_LIST_STRUCT_XrBodyJointLocationsFB(_) \ + _(type) \ + _(next) \ + _(isActive) \ + _(confidence) \ + _(jointCount) \ + _(jointLocations) \ + _(skeletonChangedCount) \ + _(time) \ + /// Calls your macro with the name of each member of XrInteractionProfileDpadBindingEXT, in order. #define XR_LIST_STRUCT_XrInteractionProfileDpadBindingEXT(_) \ _(type) \ @@ -2731,6 +3155,27 @@ XR_ENUM_STR(XrResult); _(markerId) \ _(poseInMarkerSpace) \ +/// Calls your macro with the name of each member of XrFrameEndInfoML, in order. +#define XR_LIST_STRUCT_XrFrameEndInfoML(_) \ + _(type) \ + _(next) \ + _(focusDistance) \ + _(flags) \ + +/// Calls your macro with the name of each member of XrGlobalDimmerFrameEndInfoML, in order. +#define XR_LIST_STRUCT_XrGlobalDimmerFrameEndInfoML(_) \ + _(type) \ + _(next) \ + _(dimmerValue) \ + _(flags) \ + +/// Calls your macro with the name of each member of XrCoordinateSpaceCreateInfoML, in order. +#define XR_LIST_STRUCT_XrCoordinateSpaceCreateInfoML(_) \ + _(type) \ + _(next) \ + _(cfuid) \ + _(poseInCoordinateSpace) \ + /// Calls your macro with the name of each member of XrSpatialAnchorPersistenceNameMSFT, in order. #define XR_LIST_STRUCT_XrSpatialAnchorPersistenceNameMSFT(_) \ _(name) \ @@ -2895,6 +3340,22 @@ XR_ENUM_STR(XrResult); _(maxAnisotropy) \ _(borderColor) \ +/// Calls your macro with the name of each member of XrSpaceShareInfoFB, in order. +#define XR_LIST_STRUCT_XrSpaceShareInfoFB(_) \ + _(type) \ + _(next) \ + _(spaceCount) \ + _(spaces) \ + _(userCount) \ + _(users) \ + +/// Calls your macro with the name of each member of XrEventDataSpaceShareCompleteFB, in order. +#define XR_LIST_STRUCT_XrEventDataSpaceShareCompleteFB(_) \ + _(type) \ + _(next) \ + _(requestId) \ + _(result) \ + /// Calls your macro with the name of each member of XrCompositionLayerSpaceWarpInfoFB, in order. #define XR_LIST_STRUCT_XrCompositionLayerSpaceWarpInfoFB(_) \ _(type) \ @@ -2915,6 +3376,14 @@ XR_ENUM_STR(XrResult); _(recommendedMotionVectorImageRectWidth) \ _(recommendedMotionVectorImageRectHeight) \ +/// Calls your macro with the name of each member of XrHapticAmplitudeEnvelopeVibrationFB, in order. +#define XR_LIST_STRUCT_XrHapticAmplitudeEnvelopeVibrationFB(_) \ + _(type) \ + _(next) \ + _(duration) \ + _(amplitudeCount) \ + _(amplitudes) \ + /// Calls your macro with the name of each member of XrExtent3DfFB, in order. #define XR_LIST_STRUCT_XrExtent3DfFB(_) \ _(width) \ @@ -2958,12 +3427,33 @@ XR_ENUM_STR(XrResult); _(vertexCountOutput) \ _(vertices) \ +/// Calls your macro with the name of each member of XrSemanticLabelsSupportInfoFB, in order. +#define XR_LIST_STRUCT_XrSemanticLabelsSupportInfoFB(_) \ + _(type) \ + _(next) \ + _(flags) \ + _(recognizedLabels) \ + /// Calls your macro with the name of each member of XrDigitalLensControlALMALENCE, in order. #define XR_LIST_STRUCT_XrDigitalLensControlALMALENCE(_) \ _(type) \ _(next) \ _(flags) \ +/// Calls your macro with the name of each member of XrEventDataSceneCaptureCompleteFB, in order. +#define XR_LIST_STRUCT_XrEventDataSceneCaptureCompleteFB(_) \ + _(type) \ + _(next) \ + _(requestId) \ + _(result) \ + +/// Calls your macro with the name of each member of XrSceneCaptureRequestInfoFB, in order. +#define XR_LIST_STRUCT_XrSceneCaptureRequestInfoFB(_) \ + _(type) \ + _(next) \ + _(requestByteCount) \ + _(request) \ + /// Calls your macro with the name of each member of XrSpaceContainerFB, in order. #define XR_LIST_STRUCT_XrSpaceContainerFB(_) \ _(type) \ @@ -2972,6 +3462,90 @@ XR_ENUM_STR(XrResult); _(uuidCountOutput) \ _(uuids) \ +/// Calls your macro with the name of each member of XrFoveationEyeTrackedProfileCreateInfoMETA, in order. +#define XR_LIST_STRUCT_XrFoveationEyeTrackedProfileCreateInfoMETA(_) \ + _(type) \ + _(next) \ + _(flags) \ + +/// Calls your macro with the name of each member of XrFoveationEyeTrackedStateMETA, in order. +#define XR_LIST_STRUCT_XrFoveationEyeTrackedStateMETA(_) \ + _(type) \ + _(next) \ + _(foveationCenter) \ + _(flags) \ + +/// Calls your macro with the name of each member of XrSystemFoveationEyeTrackedPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemFoveationEyeTrackedPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(supportsFoveationEyeTracked) \ + +/// Calls your macro with the name of each member of XrSystemFaceTrackingPropertiesFB, in order. +#define XR_LIST_STRUCT_XrSystemFaceTrackingPropertiesFB(_) \ + _(type) \ + _(next) \ + _(supportsFaceTracking) \ + +/// Calls your macro with the name of each member of XrFaceTrackerCreateInfoFB, in order. +#define XR_LIST_STRUCT_XrFaceTrackerCreateInfoFB(_) \ + _(type) \ + _(next) \ + _(faceExpressionSet) \ + +/// Calls your macro with the name of each member of XrFaceExpressionInfoFB, in order. +#define XR_LIST_STRUCT_XrFaceExpressionInfoFB(_) \ + _(type) \ + _(next) \ + _(time) \ + +/// Calls your macro with the name of each member of XrFaceExpressionStatusFB, in order. +#define XR_LIST_STRUCT_XrFaceExpressionStatusFB(_) \ + _(isValid) \ + _(isEyeFollowingBlendshapesValid) \ + +/// Calls your macro with the name of each member of XrFaceExpressionWeightsFB, in order. +#define XR_LIST_STRUCT_XrFaceExpressionWeightsFB(_) \ + _(type) \ + _(next) \ + _(weightCount) \ + _(weights) \ + _(confidenceCount) \ + _(confidences) \ + _(status) \ + _(time) \ + +/// Calls your macro with the name of each member of XrEyeGazeFB, in order. +#define XR_LIST_STRUCT_XrEyeGazeFB(_) \ + _(isValid) \ + _(gazePose) \ + _(gazeConfidence) \ + +/// Calls your macro with the name of each member of XrEyeTrackerCreateInfoFB, in order. +#define XR_LIST_STRUCT_XrEyeTrackerCreateInfoFB(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrEyeGazesInfoFB, in order. +#define XR_LIST_STRUCT_XrEyeGazesInfoFB(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + +/// Calls your macro with the name of each member of XrSystemEyeTrackingPropertiesFB, in order. +#define XR_LIST_STRUCT_XrSystemEyeTrackingPropertiesFB(_) \ + _(type) \ + _(next) \ + _(supportsEyeTracking) \ + +/// Calls your macro with the name of each member of XrEyeGazesFB, in order. +#define XR_LIST_STRUCT_XrEyeGazesFB(_) \ + _(type) \ + _(next) \ + _(gaze) \ + _(time) \ + /// Calls your macro with the name of each member of XrPassthroughKeyboardHandsIntensityFB, in order. #define XR_LIST_STRUCT_XrPassthroughKeyboardHandsIntensityFB(_) \ _(type) \ @@ -2985,6 +3559,163 @@ XR_ENUM_STR(XrResult); _(next) \ _(layerFlags) \ +/// Calls your macro with the name of each member of XrHapticPcmVibrationFB, in order. +#define XR_LIST_STRUCT_XrHapticPcmVibrationFB(_) \ + _(type) \ + _(next) \ + _(bufferSize) \ + _(buffer) \ + _(sampleRate) \ + _(append) \ + _(samplesConsumed) \ + +/// Calls your macro with the name of each member of XrDevicePcmSampleRateStateFB, in order. +#define XR_LIST_STRUCT_XrDevicePcmSampleRateStateFB(_) \ + _(type) \ + _(next) \ + _(sampleRate) \ + +/// Calls your macro with the name of each member of XrCompositionLayerDepthTestFB, in order. +#define XR_LIST_STRUCT_XrCompositionLayerDepthTestFB(_) \ + _(type) \ + _(next) \ + _(depthMask) \ + _(compareOp) \ + +/// Calls your macro with the name of each member of XrLocalDimmingFrameEndInfoMETA, in order. +#define XR_LIST_STRUCT_XrLocalDimmingFrameEndInfoMETA(_) \ + _(type) \ + _(next) \ + _(localDimmingMode) \ + +/// Calls your macro with the name of each member of XrSystemVirtualKeyboardPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemVirtualKeyboardPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(supportsVirtualKeyboard) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardCreateInfoMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardCreateInfoMETA(_) \ + _(type) \ + _(next) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardSpaceCreateInfoMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardSpaceCreateInfoMETA(_) \ + _(type) \ + _(next) \ + _(locationType) \ + _(space) \ + _(poseInSpace) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardLocationInfoMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardLocationInfoMETA(_) \ + _(type) \ + _(next) \ + _(locationType) \ + _(space) \ + _(poseInSpace) \ + _(scale) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardModelVisibilitySetInfoMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardModelVisibilitySetInfoMETA(_) \ + _(type) \ + _(next) \ + _(visible) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardAnimationStateMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardAnimationStateMETA(_) \ + _(type) \ + _(next) \ + _(animationIndex) \ + _(fraction) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardModelAnimationStatesMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardModelAnimationStatesMETA(_) \ + _(type) \ + _(next) \ + _(stateCapacityInput) \ + _(stateCountOutput) \ + _(states) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardTextureDataMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardTextureDataMETA(_) \ + _(type) \ + _(next) \ + _(textureWidth) \ + _(textureHeight) \ + _(bufferCapacityInput) \ + _(bufferCountOutput) \ + _(buffer) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardInputInfoMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardInputInfoMETA(_) \ + _(type) \ + _(next) \ + _(inputSource) \ + _(inputSpace) \ + _(inputPoseInSpace) \ + _(inputState) \ + +/// Calls your macro with the name of each member of XrVirtualKeyboardTextContextChangeInfoMETA, in order. +#define XR_LIST_STRUCT_XrVirtualKeyboardTextContextChangeInfoMETA(_) \ + _(type) \ + _(next) \ + _(textContext) \ + +/// Calls your macro with the name of each member of XrEventDataVirtualKeyboardCommitTextMETA, in order. +#define XR_LIST_STRUCT_XrEventDataVirtualKeyboardCommitTextMETA(_) \ + _(type) \ + _(next) \ + _(keyboard) \ + _(text) \ + +/// Calls your macro with the name of each member of XrEventDataVirtualKeyboardBackspaceMETA, in order. +#define XR_LIST_STRUCT_XrEventDataVirtualKeyboardBackspaceMETA(_) \ + _(type) \ + _(next) \ + _(keyboard) \ + +/// Calls your macro with the name of each member of XrEventDataVirtualKeyboardEnterMETA, in order. +#define XR_LIST_STRUCT_XrEventDataVirtualKeyboardEnterMETA(_) \ + _(type) \ + _(next) \ + _(keyboard) \ + +/// Calls your macro with the name of each member of XrEventDataVirtualKeyboardShownMETA, in order. +#define XR_LIST_STRUCT_XrEventDataVirtualKeyboardShownMETA(_) \ + _(type) \ + _(next) \ + _(keyboard) \ + +/// Calls your macro with the name of each member of XrEventDataVirtualKeyboardHiddenMETA, in order. +#define XR_LIST_STRUCT_XrEventDataVirtualKeyboardHiddenMETA(_) \ + _(type) \ + _(next) \ + _(keyboard) \ + +/// Calls your macro with the name of each member of XrExternalCameraIntrinsicsOCULUS, in order. +#define XR_LIST_STRUCT_XrExternalCameraIntrinsicsOCULUS(_) \ + _(lastChangeTime) \ + _(fov) \ + _(virtualNearPlaneDistance) \ + _(virtualFarPlaneDistance) \ + _(imageSensorPixelResolution) \ + +/// Calls your macro with the name of each member of XrExternalCameraExtrinsicsOCULUS, in order. +#define XR_LIST_STRUCT_XrExternalCameraExtrinsicsOCULUS(_) \ + _(lastChangeTime) \ + _(cameraStatusFlags) \ + _(attachedToDevice) \ + _(relativePose) \ + +/// Calls your macro with the name of each member of XrExternalCameraOCULUS, in order. +#define XR_LIST_STRUCT_XrExternalCameraOCULUS(_) \ + _(type) \ + _(next) \ + _(name) \ + _(intrinsics) \ + _(extrinsics) \ + /// Calls your macro with the name of each member of XrVulkanSwapchainCreateInfoMETA, in order. #define XR_LIST_STRUCT_XrVulkanSwapchainCreateInfoMETA(_) \ _(type) \ @@ -3007,12 +3738,73 @@ XR_ENUM_STR(XrResult); _(uintValue) \ _(floatValue) \ +/// Calls your macro with the name of each member of XrSpaceListSaveInfoFB, in order. +#define XR_LIST_STRUCT_XrSpaceListSaveInfoFB(_) \ + _(type) \ + _(next) \ + _(spaceCount) \ + _(spaces) \ + _(location) \ + +/// Calls your macro with the name of each member of XrEventDataSpaceListSaveCompleteFB, in order. +#define XR_LIST_STRUCT_XrEventDataSpaceListSaveCompleteFB(_) \ + _(type) \ + _(next) \ + _(requestId) \ + _(result) \ + +/// Calls your macro with the name of each member of XrSpaceUserCreateInfoFB, in order. +#define XR_LIST_STRUCT_XrSpaceUserCreateInfoFB(_) \ + _(type) \ + _(next) \ + _(userId) \ + /// Calls your macro with the name of each member of XrSystemHeadsetIdPropertiesMETA, in order. #define XR_LIST_STRUCT_XrSystemHeadsetIdPropertiesMETA(_) \ _(type) \ _(next) \ _(id) \ +/// Calls your macro with the name of each member of XrPassthroughColorLutDataMETA, in order. +#define XR_LIST_STRUCT_XrPassthroughColorLutDataMETA(_) \ + _(bufferSize) \ + _(buffer) \ + +/// Calls your macro with the name of each member of XrPassthroughColorLutCreateInfoMETA, in order. +#define XR_LIST_STRUCT_XrPassthroughColorLutCreateInfoMETA(_) \ + _(type) \ + _(next) \ + _(channels) \ + _(resolution) \ + _(data) \ + +/// Calls your macro with the name of each member of XrPassthroughColorLutUpdateInfoMETA, in order. +#define XR_LIST_STRUCT_XrPassthroughColorLutUpdateInfoMETA(_) \ + _(type) \ + _(next) \ + _(data) \ + +/// Calls your macro with the name of each member of XrPassthroughColorMapLutMETA, in order. +#define XR_LIST_STRUCT_XrPassthroughColorMapLutMETA(_) \ + _(type) \ + _(next) \ + _(colorLut) \ + _(weight) \ + +/// Calls your macro with the name of each member of XrPassthroughColorMapInterpolatedLutMETA, in order. +#define XR_LIST_STRUCT_XrPassthroughColorMapInterpolatedLutMETA(_) \ + _(type) \ + _(next) \ + _(sourceColorLut) \ + _(targetColorLut) \ + _(weight) \ + +/// Calls your macro with the name of each member of XrSystemPassthroughColorLutPropertiesMETA, in order. +#define XR_LIST_STRUCT_XrSystemPassthroughColorLutPropertiesMETA(_) \ + _(type) \ + _(next) \ + _(maxColorLutResolution) \ + /// Calls your macro with the name of each member of XrPassthroughCreateInfoHTC, in order. #define XR_LIST_STRUCT_XrPassthroughCreateInfoHTC(_) \ _(type) \ @@ -3086,6 +3878,106 @@ XR_ENUM_STR(XrResult); _(actionSetPriorityCount) \ _(actionSetPriorities) \ +/// Calls your macro with the name of each member of XrSystemForceFeedbackCurlPropertiesMNDX, in order. +#define XR_LIST_STRUCT_XrSystemForceFeedbackCurlPropertiesMNDX(_) \ + _(type) \ + _(next) \ + _(supportsForceFeedbackCurl) \ + +/// Calls your macro with the name of each member of XrForceFeedbackCurlApplyLocationMNDX, in order. +#define XR_LIST_STRUCT_XrForceFeedbackCurlApplyLocationMNDX(_) \ + _(location) \ + _(value) \ + +/// Calls your macro with the name of each member of XrForceFeedbackCurlApplyLocationsMNDX, in order. +#define XR_LIST_STRUCT_XrForceFeedbackCurlApplyLocationsMNDX(_) \ + _(type) \ + _(next) \ + _(locationCount) \ + _(locations) \ + +/// Calls your macro with the name of each member of XrHandTrackingDataSourceInfoEXT, in order. +#define XR_LIST_STRUCT_XrHandTrackingDataSourceInfoEXT(_) \ + _(type) \ + _(next) \ + _(requestedDataSourceCount) \ + _(requestedDataSources) \ + +/// Calls your macro with the name of each member of XrHandTrackingDataSourceStateEXT, in order. +#define XR_LIST_STRUCT_XrHandTrackingDataSourceStateEXT(_) \ + _(type) \ + _(next) \ + _(isActive) \ + _(dataSource) \ + +/// Calls your macro with the name of each member of XrSystemPlaneDetectionPropertiesEXT, in order. +#define XR_LIST_STRUCT_XrSystemPlaneDetectionPropertiesEXT(_) \ + _(type) \ + _(next) \ + _(supportedFeatures) \ + +/// Calls your macro with the name of each member of XrPlaneDetectorCreateInfoEXT, in order. +#define XR_LIST_STRUCT_XrPlaneDetectorCreateInfoEXT(_) \ + _(type) \ + _(next) \ + _(flags) \ + +/// Calls your macro with the name of each member of XrExtent3DfEXT, in order. +#define XR_LIST_STRUCT_XrExtent3DfEXT(_) \ + _(width) \ + _(height) \ + _(depth) \ + +/// Calls your macro with the name of each member of XrPlaneDetectorBeginInfoEXT, in order. +#define XR_LIST_STRUCT_XrPlaneDetectorBeginInfoEXT(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + _(orientationCount) \ + _(orientations) \ + _(semanticTypeCount) \ + _(semanticTypes) \ + _(maxPlanes) \ + _(minArea) \ + _(boundingBoxPose) \ + _(boundingBoxExtent) \ + +/// Calls your macro with the name of each member of XrPlaneDetectorGetInfoEXT, in order. +#define XR_LIST_STRUCT_XrPlaneDetectorGetInfoEXT(_) \ + _(type) \ + _(next) \ + _(baseSpace) \ + _(time) \ + +/// Calls your macro with the name of each member of XrPlaneDetectorLocationEXT, in order. +#define XR_LIST_STRUCT_XrPlaneDetectorLocationEXT(_) \ + _(type) \ + _(next) \ + _(planeId) \ + _(locationFlags) \ + _(pose) \ + _(extents) \ + _(orientation) \ + _(semanticType) \ + _(polygonBufferCount) \ + +/// Calls your macro with the name of each member of XrPlaneDetectorLocationsEXT, in order. +#define XR_LIST_STRUCT_XrPlaneDetectorLocationsEXT(_) \ + _(type) \ + _(next) \ + _(planeLocationCapacityInput) \ + _(planeLocationCountOutput) \ + _(planeLocations) \ + +/// Calls your macro with the name of each member of XrPlaneDetectorPolygonBufferEXT, in order. +#define XR_LIST_STRUCT_XrPlaneDetectorPolygonBufferEXT(_) \ + _(type) \ + _(next) \ + _(vertexCapacityInput) \ + _(vertexCountOutput) \ + _(vertices) \ + /// Calls your macro with the structure type name and the XrStructureType constant for @@ -3104,6 +3996,7 @@ XR_ENUM_STR(XrResult); XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_) \ XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_) \ XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_) \ + XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_) \ XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_) \ @@ -3210,6 +4103,11 @@ XR_ENUM_STR(XrResult); _(XrCompositionLayerReprojectionInfoMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_INFO_MSFT) \ _(XrCompositionLayerReprojectionPlaneOverrideMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT) \ _(XrCompositionLayerSecureContentFB, XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB) \ + _(XrSystemBodyTrackingPropertiesFB, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_FB) \ + _(XrBodyTrackerCreateInfoFB, XR_TYPE_BODY_TRACKER_CREATE_INFO_FB) \ + _(XrBodySkeletonFB, XR_TYPE_BODY_SKELETON_FB) \ + _(XrBodyJointsLocateInfoFB, XR_TYPE_BODY_JOINTS_LOCATE_INFO_FB) \ + _(XrBodyJointLocationsFB, XR_TYPE_BODY_JOINT_LOCATIONS_FB) \ _(XrInteractionProfileDpadBindingEXT, XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT) \ _(XrInteractionProfileAnalogThresholdVALVE, XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE) \ _(XrHandJointsMotionRangeInfoEXT, XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT) \ @@ -3284,6 +4182,8 @@ XR_ENUM_STR(XrResult); _(XrSystemMarkerTrackingPropertiesVARJO, XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO) \ _(XrEventDataMarkerTrackingUpdateVARJO, XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO) \ _(XrMarkerSpaceCreateInfoVARJO, XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO) \ + _(XrFrameEndInfoML, XR_TYPE_FRAME_END_INFO_ML) \ + _(XrGlobalDimmerFrameEndInfoML, XR_TYPE_GLOBAL_DIMMER_FRAME_END_INFO_ML) \ _(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \ _(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \ _(XrSpaceQueryInfoFB, XR_TYPE_SPACE_QUERY_INFO_FB) \ @@ -3297,18 +4197,63 @@ XR_ENUM_STR(XrResult); _(XrSpaceEraseInfoFB, XR_TYPE_SPACE_ERASE_INFO_FB) \ _(XrEventDataSpaceSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB) \ _(XrEventDataSpaceEraseCompleteFB, XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB) \ + _(XrSpaceShareInfoFB, XR_TYPE_SPACE_SHARE_INFO_FB) \ + _(XrEventDataSpaceShareCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB) \ _(XrCompositionLayerSpaceWarpInfoFB, XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB) \ _(XrSystemSpaceWarpPropertiesFB, XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB) \ + _(XrHapticAmplitudeEnvelopeVibrationFB, XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB) \ _(XrSemanticLabelsFB, XR_TYPE_SEMANTIC_LABELS_FB) \ _(XrRoomLayoutFB, XR_TYPE_ROOM_LAYOUT_FB) \ _(XrBoundary2DFB, XR_TYPE_BOUNDARY_2D_FB) \ + _(XrSemanticLabelsSupportInfoFB, XR_TYPE_SEMANTIC_LABELS_SUPPORT_INFO_FB) \ _(XrDigitalLensControlALMALENCE, XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE) \ + _(XrEventDataSceneCaptureCompleteFB, XR_TYPE_EVENT_DATA_SCENE_CAPTURE_COMPLETE_FB) \ + _(XrSceneCaptureRequestInfoFB, XR_TYPE_SCENE_CAPTURE_REQUEST_INFO_FB) \ _(XrSpaceContainerFB, XR_TYPE_SPACE_CONTAINER_FB) \ + _(XrFoveationEyeTrackedProfileCreateInfoMETA, XR_TYPE_FOVEATION_EYE_TRACKED_PROFILE_CREATE_INFO_META) \ + _(XrFoveationEyeTrackedStateMETA, XR_TYPE_FOVEATION_EYE_TRACKED_STATE_META) \ + _(XrSystemFoveationEyeTrackedPropertiesMETA, XR_TYPE_SYSTEM_FOVEATION_EYE_TRACKED_PROPERTIES_META) \ + _(XrSystemFaceTrackingPropertiesFB, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_FB) \ + _(XrFaceTrackerCreateInfoFB, XR_TYPE_FACE_TRACKER_CREATE_INFO_FB) \ + _(XrFaceExpressionInfoFB, XR_TYPE_FACE_EXPRESSION_INFO_FB) \ + _(XrFaceExpressionWeightsFB, XR_TYPE_FACE_EXPRESSION_WEIGHTS_FB) \ + _(XrEyeTrackerCreateInfoFB, XR_TYPE_EYE_TRACKER_CREATE_INFO_FB) \ + _(XrEyeGazesInfoFB, XR_TYPE_EYE_GAZES_INFO_FB) \ + _(XrSystemEyeTrackingPropertiesFB, XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_FB) \ + _(XrEyeGazesFB, XR_TYPE_EYE_GAZES_FB) \ _(XrPassthroughKeyboardHandsIntensityFB, XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB) \ _(XrCompositionLayerSettingsFB, XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB) \ + _(XrHapticPcmVibrationFB, XR_TYPE_HAPTIC_PCM_VIBRATION_FB) \ + _(XrDevicePcmSampleRateStateFB, XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB) \ + _(XrCompositionLayerDepthTestFB, XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_FB) \ + _(XrLocalDimmingFrameEndInfoMETA, XR_TYPE_LOCAL_DIMMING_FRAME_END_INFO_META) \ + _(XrSystemVirtualKeyboardPropertiesMETA, XR_TYPE_SYSTEM_VIRTUAL_KEYBOARD_PROPERTIES_META) \ + _(XrVirtualKeyboardCreateInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_CREATE_INFO_META) \ + _(XrVirtualKeyboardSpaceCreateInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_SPACE_CREATE_INFO_META) \ + _(XrVirtualKeyboardLocationInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_LOCATION_INFO_META) \ + _(XrVirtualKeyboardModelVisibilitySetInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_MODEL_VISIBILITY_SET_INFO_META) \ + _(XrVirtualKeyboardAnimationStateMETA, XR_TYPE_VIRTUAL_KEYBOARD_ANIMATION_STATE_META) \ + _(XrVirtualKeyboardModelAnimationStatesMETA, XR_TYPE_VIRTUAL_KEYBOARD_MODEL_ANIMATION_STATES_META) \ + _(XrVirtualKeyboardTextureDataMETA, XR_TYPE_VIRTUAL_KEYBOARD_TEXTURE_DATA_META) \ + _(XrVirtualKeyboardInputInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_INPUT_INFO_META) \ + _(XrVirtualKeyboardTextContextChangeInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_TEXT_CONTEXT_CHANGE_INFO_META) \ + _(XrEventDataVirtualKeyboardCommitTextMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_COMMIT_TEXT_META) \ + _(XrEventDataVirtualKeyboardBackspaceMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_BACKSPACE_META) \ + _(XrEventDataVirtualKeyboardEnterMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_ENTER_META) \ + _(XrEventDataVirtualKeyboardShownMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_SHOWN_META) \ + _(XrEventDataVirtualKeyboardHiddenMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_HIDDEN_META) \ + _(XrExternalCameraOCULUS, XR_TYPE_EXTERNAL_CAMERA_OCULUS) \ _(XrPerformanceMetricsStateMETA, XR_TYPE_PERFORMANCE_METRICS_STATE_META) \ _(XrPerformanceMetricsCounterMETA, XR_TYPE_PERFORMANCE_METRICS_COUNTER_META) \ + _(XrSpaceListSaveInfoFB, XR_TYPE_SPACE_LIST_SAVE_INFO_FB) \ + _(XrEventDataSpaceListSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB) \ + _(XrSpaceUserCreateInfoFB, XR_TYPE_SPACE_USER_CREATE_INFO_FB) \ _(XrSystemHeadsetIdPropertiesMETA, XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META) \ + _(XrPassthroughColorLutCreateInfoMETA, XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META) \ + _(XrPassthroughColorLutUpdateInfoMETA, XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META) \ + _(XrPassthroughColorMapLutMETA, XR_TYPE_PASSTHROUGH_COLOR_MAP_LUT_META) \ + _(XrPassthroughColorMapInterpolatedLutMETA, XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META) \ + _(XrSystemPassthroughColorLutPropertiesMETA, XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META) \ _(XrPassthroughCreateInfoHTC, XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC) \ _(XrPassthroughColorHTC, XR_TYPE_PASSTHROUGH_COLOR_HTC) \ _(XrPassthroughMeshTransformInfoHTC, XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC) \ @@ -3317,6 +4262,17 @@ XR_ENUM_STR(XrResult); _(XrFoveationDynamicModeInfoHTC, XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC) \ _(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \ _(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \ + _(XrSystemForceFeedbackCurlPropertiesMNDX, XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX) \ + _(XrForceFeedbackCurlApplyLocationsMNDX, XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX) \ + _(XrHandTrackingDataSourceInfoEXT, XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT) \ + _(XrHandTrackingDataSourceStateEXT, XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT) \ + _(XrSystemPlaneDetectionPropertiesEXT, XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT) \ + _(XrPlaneDetectorCreateInfoEXT, XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT) \ + _(XrPlaneDetectorBeginInfoEXT, XR_TYPE_PLANE_DETECTOR_BEGIN_INFO_EXT) \ + _(XrPlaneDetectorGetInfoEXT, XR_TYPE_PLANE_DETECTOR_GET_INFO_EXT) \ + _(XrPlaneDetectorLocationEXT, XR_TYPE_PLANE_DETECTOR_LOCATION_EXT) \ + _(XrPlaneDetectorLocationsEXT, XR_TYPE_PLANE_DETECTOR_LOCATIONS_EXT) \ + _(XrPlaneDetectorPolygonBufferEXT, XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT) \ #if defined(XR_USE_GRAPHICS_API_D3D11) @@ -3458,6 +4414,16 @@ XR_ENUM_STR(XrResult); #define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_) #endif +#if defined(XR_USE_PLATFORM_ML) +/// Implementation detail of XR_LIST_STRUCTURE_TYPES() +/// Structure types available only when XR_USE_PLATFORM_ML is defined +#define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_) \ + _(XrCoordinateSpaceCreateInfoML, XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML) \ + +#else +#define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_) +#endif + #if defined(XR_USE_PLATFORM_WIN32) /// Implementation detail of XR_LIST_STRUCTURE_TYPES() /// Structure types available only when XR_USE_PLATFORM_WIN32 is defined @@ -3521,6 +4487,7 @@ XR_ENUM_STR(XrResult); _(XR_FB_android_surface_swapchain_create, 71) \ _(XR_FB_swapchain_update_state, 72) \ _(XR_FB_composition_layer_secure_content, 73) \ + _(XR_FB_body_tracking, 77) \ _(XR_EXT_dpad_binding, 79) \ _(XR_VALVE_analog_threshold, 80) \ _(XR_EXT_hand_joints_motion_range, 81) \ @@ -3558,6 +4525,9 @@ XR_ENUM_STR(XrResult); _(XR_VARJO_marker_tracking, 125) \ _(XR_VARJO_view_offset, 126) \ _(XR_ML_ml2_controller_interaction, 135) \ + _(XR_ML_frame_end_info, 136) \ + _(XR_ML_global_dimmer, 137) \ + _(XR_ML_compat, 138) \ _(XR_MSFT_spatial_anchor_persistence, 143) \ _(XR_ULTRALEAP_hand_tracking_forearm, 150) \ _(XR_FB_spatial_entity_query, 157) \ @@ -3568,20 +4538,44 @@ XR_ENUM_STR(XrResult); _(XR_FB_swapchain_update_state_opengl_es, 163) \ _(XR_FB_swapchain_update_state_vulkan, 164) \ _(XR_KHR_swapchain_usage_input_attachment_bit, 166) \ + _(XR_FB_touch_controller_pro, 168) \ + _(XR_FB_spatial_entity_sharing, 170) \ _(XR_FB_space_warp, 172) \ + _(XR_FB_haptic_amplitude_envelope, 174) \ _(XR_FB_scene, 176) \ _(XR_EXT_palm_pose, 177) \ _(XR_ALMALENCE_digital_lens_control, 197) \ + _(XR_FB_scene_capture, 199) \ _(XR_FB_spatial_entity_container, 200) \ + _(XR_META_foveation_eye_tracked, 201) \ + _(XR_FB_face_tracking, 202) \ + _(XR_FB_eye_tracking_social, 203) \ _(XR_FB_passthrough_keyboard_hands, 204) \ _(XR_FB_composition_layer_settings, 205) \ + _(XR_FB_touch_controller_proximity, 207) \ + _(XR_FB_haptic_pcm, 210) \ + _(XR_FB_composition_layer_depth_test, 213) \ + _(XR_META_local_dimming, 217) \ + _(XR_META_virtual_keyboard, 220) \ + _(XR_OCULUS_external_camera, 227) \ _(XR_META_vulkan_swapchain_create_info, 228) \ _(XR_META_performance_metrics, 233) \ + _(XR_FB_spatial_entity_storage_batch, 239) \ + _(XR_FB_spatial_entity_user, 242) \ _(XR_META_headset_id, 246) \ + _(XR_META_passthrough_color_lut, 267) \ _(XR_EXT_uuid, 300) \ + _(XR_EXT_hand_interaction, 303) \ + _(XR_QCOM_tracking_optimization_settings, 307) \ _(XR_HTC_passthrough, 318) \ _(XR_HTC_foveation, 319) \ _(XR_EXT_active_action_set_priority, 374) \ + _(XR_MNDX_force_feedback_curl, 376) \ + _(XR_BD_controller_interaction, 385) \ + _(XR_EXT_local_floor, 427) \ + _(XR_EXT_hand_tracking_data_source, 429) \ + _(XR_EXT_plane_detection, 430) \ + _(XR_OPPO_controller_interaction, 454) \ #endif diff --git a/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h b/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h index 19b0e1c3f6..d0d05e97d0 100644 --- a/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h +++ b/thirdparty/openxr/include/openxr/openxr_reflection_parent_structs.h @@ -2,7 +2,7 @@ #define OPENXR_REFLECTION_PARENT_STRUCTS_H_ 1 /* -** Copyright (c) 2017-2022, The Khronos Group Inc. +** Copyright (c) 2017-2023, The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -62,6 +62,8 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a _avail(XrEventDataSpaceQueryCompleteFB, XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB) \ _avail(XrEventDataSpaceSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB) \ _avail(XrEventDataSpaceEraseCompleteFB, XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB) \ + _avail(XrEventDataSpaceShareCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB) \ + _avail(XrEventDataSpaceListSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB) \ @@ -75,6 +77,8 @@ This file contains expansion macros (X Macros) for OpenXR structures that have a // Implementation detail of XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader() #define _impl_XR_LIST_ALL_CHILD_STRUCTURE_TYPES_XrHapticBaseHeader_CORE(_avail, _unavail) \ _avail(XrHapticVibration, XR_TYPE_HAPTIC_VIBRATION) \ + _avail(XrHapticAmplitudeEnvelopeVibrationFB, XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB) \ + _avail(XrHapticPcmVibrationFB, XR_TYPE_HAPTIC_PCM_VIBRATION_FB) \ diff --git a/thirdparty/openxr/include/openxr/openxr_reflection_structs.h b/thirdparty/openxr/include/openxr/openxr_reflection_structs.h index 300bbbad6d..ec186390a3 100644 --- a/thirdparty/openxr/include/openxr/openxr_reflection_structs.h +++ b/thirdparty/openxr/include/openxr/openxr_reflection_structs.h @@ -2,7 +2,7 @@ #define OPENXR_REFLECTION_STRUCTS_H_ 1 /* -** Copyright (c) 2017-2022, The Khronos Group Inc. +** Copyright (c) 2017-2023, The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -37,6 +37,7 @@ This file contains expansion macros (X Macros) for OpenXR structures. _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_avail, _unavail) \ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_avail, _unavail) \ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_avail, _unavail) \ + _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_avail, _unavail) \ _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ @@ -143,6 +144,11 @@ This file contains expansion macros (X Macros) for OpenXR structures. _avail(XrCompositionLayerReprojectionInfoMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_INFO_MSFT) \ _avail(XrCompositionLayerReprojectionPlaneOverrideMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT) \ _avail(XrCompositionLayerSecureContentFB, XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB) \ + _avail(XrSystemBodyTrackingPropertiesFB, XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_FB) \ + _avail(XrBodyTrackerCreateInfoFB, XR_TYPE_BODY_TRACKER_CREATE_INFO_FB) \ + _avail(XrBodySkeletonFB, XR_TYPE_BODY_SKELETON_FB) \ + _avail(XrBodyJointsLocateInfoFB, XR_TYPE_BODY_JOINTS_LOCATE_INFO_FB) \ + _avail(XrBodyJointLocationsFB, XR_TYPE_BODY_JOINT_LOCATIONS_FB) \ _avail(XrInteractionProfileDpadBindingEXT, XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT) \ _avail(XrInteractionProfileAnalogThresholdVALVE, XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE) \ _avail(XrHandJointsMotionRangeInfoEXT, XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT) \ @@ -217,6 +223,8 @@ This file contains expansion macros (X Macros) for OpenXR structures. _avail(XrSystemMarkerTrackingPropertiesVARJO, XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO) \ _avail(XrEventDataMarkerTrackingUpdateVARJO, XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO) \ _avail(XrMarkerSpaceCreateInfoVARJO, XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO) \ + _avail(XrFrameEndInfoML, XR_TYPE_FRAME_END_INFO_ML) \ + _avail(XrGlobalDimmerFrameEndInfoML, XR_TYPE_GLOBAL_DIMMER_FRAME_END_INFO_ML) \ _avail(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \ _avail(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \ _avail(XrSpaceQueryInfoFB, XR_TYPE_SPACE_QUERY_INFO_FB) \ @@ -230,18 +238,63 @@ This file contains expansion macros (X Macros) for OpenXR structures. _avail(XrSpaceEraseInfoFB, XR_TYPE_SPACE_ERASE_INFO_FB) \ _avail(XrEventDataSpaceSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB) \ _avail(XrEventDataSpaceEraseCompleteFB, XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB) \ + _avail(XrSpaceShareInfoFB, XR_TYPE_SPACE_SHARE_INFO_FB) \ + _avail(XrEventDataSpaceShareCompleteFB, XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB) \ _avail(XrCompositionLayerSpaceWarpInfoFB, XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB) \ _avail(XrSystemSpaceWarpPropertiesFB, XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB) \ + _avail(XrHapticAmplitudeEnvelopeVibrationFB, XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB) \ _avail(XrSemanticLabelsFB, XR_TYPE_SEMANTIC_LABELS_FB) \ _avail(XrRoomLayoutFB, XR_TYPE_ROOM_LAYOUT_FB) \ _avail(XrBoundary2DFB, XR_TYPE_BOUNDARY_2D_FB) \ + _avail(XrSemanticLabelsSupportInfoFB, XR_TYPE_SEMANTIC_LABELS_SUPPORT_INFO_FB) \ _avail(XrDigitalLensControlALMALENCE, XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE) \ + _avail(XrEventDataSceneCaptureCompleteFB, XR_TYPE_EVENT_DATA_SCENE_CAPTURE_COMPLETE_FB) \ + _avail(XrSceneCaptureRequestInfoFB, XR_TYPE_SCENE_CAPTURE_REQUEST_INFO_FB) \ _avail(XrSpaceContainerFB, XR_TYPE_SPACE_CONTAINER_FB) \ + _avail(XrFoveationEyeTrackedProfileCreateInfoMETA, XR_TYPE_FOVEATION_EYE_TRACKED_PROFILE_CREATE_INFO_META) \ + _avail(XrFoveationEyeTrackedStateMETA, XR_TYPE_FOVEATION_EYE_TRACKED_STATE_META) \ + _avail(XrSystemFoveationEyeTrackedPropertiesMETA, XR_TYPE_SYSTEM_FOVEATION_EYE_TRACKED_PROPERTIES_META) \ + _avail(XrSystemFaceTrackingPropertiesFB, XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_FB) \ + _avail(XrFaceTrackerCreateInfoFB, XR_TYPE_FACE_TRACKER_CREATE_INFO_FB) \ + _avail(XrFaceExpressionInfoFB, XR_TYPE_FACE_EXPRESSION_INFO_FB) \ + _avail(XrFaceExpressionWeightsFB, XR_TYPE_FACE_EXPRESSION_WEIGHTS_FB) \ + _avail(XrEyeTrackerCreateInfoFB, XR_TYPE_EYE_TRACKER_CREATE_INFO_FB) \ + _avail(XrEyeGazesInfoFB, XR_TYPE_EYE_GAZES_INFO_FB) \ + _avail(XrSystemEyeTrackingPropertiesFB, XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_FB) \ + _avail(XrEyeGazesFB, XR_TYPE_EYE_GAZES_FB) \ _avail(XrPassthroughKeyboardHandsIntensityFB, XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB) \ _avail(XrCompositionLayerSettingsFB, XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB) \ + _avail(XrHapticPcmVibrationFB, XR_TYPE_HAPTIC_PCM_VIBRATION_FB) \ + _avail(XrDevicePcmSampleRateStateFB, XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB) \ + _avail(XrCompositionLayerDepthTestFB, XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_FB) \ + _avail(XrLocalDimmingFrameEndInfoMETA, XR_TYPE_LOCAL_DIMMING_FRAME_END_INFO_META) \ + _avail(XrSystemVirtualKeyboardPropertiesMETA, XR_TYPE_SYSTEM_VIRTUAL_KEYBOARD_PROPERTIES_META) \ + _avail(XrVirtualKeyboardCreateInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_CREATE_INFO_META) \ + _avail(XrVirtualKeyboardSpaceCreateInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_SPACE_CREATE_INFO_META) \ + _avail(XrVirtualKeyboardLocationInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_LOCATION_INFO_META) \ + _avail(XrVirtualKeyboardModelVisibilitySetInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_MODEL_VISIBILITY_SET_INFO_META) \ + _avail(XrVirtualKeyboardAnimationStateMETA, XR_TYPE_VIRTUAL_KEYBOARD_ANIMATION_STATE_META) \ + _avail(XrVirtualKeyboardModelAnimationStatesMETA, XR_TYPE_VIRTUAL_KEYBOARD_MODEL_ANIMATION_STATES_META) \ + _avail(XrVirtualKeyboardTextureDataMETA, XR_TYPE_VIRTUAL_KEYBOARD_TEXTURE_DATA_META) \ + _avail(XrVirtualKeyboardInputInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_INPUT_INFO_META) \ + _avail(XrVirtualKeyboardTextContextChangeInfoMETA, XR_TYPE_VIRTUAL_KEYBOARD_TEXT_CONTEXT_CHANGE_INFO_META) \ + _avail(XrEventDataVirtualKeyboardCommitTextMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_COMMIT_TEXT_META) \ + _avail(XrEventDataVirtualKeyboardBackspaceMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_BACKSPACE_META) \ + _avail(XrEventDataVirtualKeyboardEnterMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_ENTER_META) \ + _avail(XrEventDataVirtualKeyboardShownMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_SHOWN_META) \ + _avail(XrEventDataVirtualKeyboardHiddenMETA, XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_HIDDEN_META) \ + _avail(XrExternalCameraOCULUS, XR_TYPE_EXTERNAL_CAMERA_OCULUS) \ _avail(XrPerformanceMetricsStateMETA, XR_TYPE_PERFORMANCE_METRICS_STATE_META) \ _avail(XrPerformanceMetricsCounterMETA, XR_TYPE_PERFORMANCE_METRICS_COUNTER_META) \ + _avail(XrSpaceListSaveInfoFB, XR_TYPE_SPACE_LIST_SAVE_INFO_FB) \ + _avail(XrEventDataSpaceListSaveCompleteFB, XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB) \ + _avail(XrSpaceUserCreateInfoFB, XR_TYPE_SPACE_USER_CREATE_INFO_FB) \ _avail(XrSystemHeadsetIdPropertiesMETA, XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META) \ + _avail(XrPassthroughColorLutCreateInfoMETA, XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META) \ + _avail(XrPassthroughColorLutUpdateInfoMETA, XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META) \ + _avail(XrPassthroughColorMapLutMETA, XR_TYPE_PASSTHROUGH_COLOR_MAP_LUT_META) \ + _avail(XrPassthroughColorMapInterpolatedLutMETA, XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META) \ + _avail(XrSystemPassthroughColorLutPropertiesMETA, XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META) \ _avail(XrPassthroughCreateInfoHTC, XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC) \ _avail(XrPassthroughColorHTC, XR_TYPE_PASSTHROUGH_COLOR_HTC) \ _avail(XrPassthroughMeshTransformInfoHTC, XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC) \ @@ -250,6 +303,17 @@ This file contains expansion macros (X Macros) for OpenXR structures. _avail(XrFoveationDynamicModeInfoHTC, XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC) \ _avail(XrFoveationCustomModeInfoHTC, XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC) \ _avail(XrActiveActionSetPrioritiesEXT, XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT) \ + _avail(XrSystemForceFeedbackCurlPropertiesMNDX, XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX) \ + _avail(XrForceFeedbackCurlApplyLocationsMNDX, XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX) \ + _avail(XrHandTrackingDataSourceInfoEXT, XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT) \ + _avail(XrHandTrackingDataSourceStateEXT, XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT) \ + _avail(XrSystemPlaneDetectionPropertiesEXT, XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT) \ + _avail(XrPlaneDetectorCreateInfoEXT, XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT) \ + _avail(XrPlaneDetectorBeginInfoEXT, XR_TYPE_PLANE_DETECTOR_BEGIN_INFO_EXT) \ + _avail(XrPlaneDetectorGetInfoEXT, XR_TYPE_PLANE_DETECTOR_GET_INFO_EXT) \ + _avail(XrPlaneDetectorLocationEXT, XR_TYPE_PLANE_DETECTOR_LOCATION_EXT) \ + _avail(XrPlaneDetectorLocationsEXT, XR_TYPE_PLANE_DETECTOR_LOCATIONS_EXT) \ + _avail(XrPlaneDetectorPolygonBufferEXT, XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT) \ #if defined(XR_USE_GRAPHICS_API_D3D11) @@ -410,6 +474,16 @@ This file contains expansion macros (X Macros) for OpenXR structures. #endif +#if defined(XR_USE_PLATFORM_ML) +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_avail, _unavail) \ + _avail(XrCoordinateSpaceCreateInfoML, XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML) \ + +#else +#define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_ML(_avail, _unavail) \ + _unavail(XrCoordinateSpaceCreateInfoML, XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML) \ + +#endif + #if defined(XR_USE_PLATFORM_WIN32) #define _impl_XR_LIST_ALL_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_avail, _unavail) \ _avail(XrHolographicWindowAttachmentMSFT, XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT) \ diff --git a/thirdparty/openxr/patches/fix-gcc13-stdint.patch b/thirdparty/openxr/patches/fix-gcc13-stdint.patch deleted file mode 100644 index 9e659eb210..0000000000 --- a/thirdparty/openxr/patches/fix-gcc13-stdint.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/thirdparty/openxr/src/common/platform_utils.hpp b/thirdparty/openxr/src/common/platform_utils.hpp -index 85d5cdab10..2d870cfea7 100644 ---- a/thirdparty/openxr/src/common/platform_utils.hpp -+++ b/thirdparty/openxr/src/common/platform_utils.hpp -@@ -11,6 +11,7 @@ - - #include "xr_dependencies.h" - #include <string> -+#include <stdint.h> - #include <stdlib.h> - - // OpenXR paths and registry key locations diff --git a/thirdparty/openxr/src/.clang-format b/thirdparty/openxr/src/.clang-format deleted file mode 100644 index 36546cab92..0000000000 --- a/thirdparty/openxr/src/.clang-format +++ /dev/null @@ -1,10 +0,0 @@ ---- -# Copyright (c) 2017-2022, The Khronos Group Inc. -# -# SPDX-License-Identifier: Apache-2.0 -# Use defaults from the Google style with the following exceptions: -BasedOnStyle: Google -IndentWidth: 4 -ColumnLimit: 132 -SortIncludes: false -... diff --git a/thirdparty/openxr/src/common/extra_algorithms.h b/thirdparty/openxr/src/common/extra_algorithms.h index 64af4d08ff..eec429e12a 100644 --- a/thirdparty/openxr/src/common/extra_algorithms.h +++ b/thirdparty/openxr/src/common/extra_algorithms.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // Copyright (c) 2019 Collabora, Ltd. diff --git a/thirdparty/openxr/src/common/filesystem_utils.cpp b/thirdparty/openxr/src/common/filesystem_utils.cpp index d3d4182fb9..16e6ff3292 100644 --- a/thirdparty/openxr/src/common/filesystem_utils.cpp +++ b/thirdparty/openxr/src/common/filesystem_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/thirdparty/openxr/src/common/filesystem_utils.hpp b/thirdparty/openxr/src/common/filesystem_utils.hpp index 4a5c987e7b..3dea1b2c3e 100644 --- a/thirdparty/openxr/src/common/filesystem_utils.hpp +++ b/thirdparty/openxr/src/common/filesystem_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/thirdparty/openxr/src/common/hex_and_handles.h b/thirdparty/openxr/src/common/hex_and_handles.h index 341013d32b..300669033f 100644 --- a/thirdparty/openxr/src/common/hex_and_handles.h +++ b/thirdparty/openxr/src/common/hex_and_handles.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // Copyright (c) 2019 Collabora, Ltd. diff --git a/thirdparty/openxr/src/common/loader_interfaces.h b/thirdparty/openxr/src/common/loader_interfaces.h index 9c74ed16f3..020c3456ea 100644 --- a/thirdparty/openxr/src/common/loader_interfaces.h +++ b/thirdparty/openxr/src/common/loader_interfaces.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/thirdparty/openxr/src/common/object_info.cpp b/thirdparty/openxr/src/common/object_info.cpp index 95b5aaf404..3f8f96bc6e 100644 --- a/thirdparty/openxr/src/common/object_info.cpp +++ b/thirdparty/openxr/src/common/object_info.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // Copyright (c) 2019 Collabora, Ltd. @@ -132,6 +132,8 @@ XrSdkSessionLabel::XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, boo : label_name(label_info.labelName), debug_utils_label(label_info), is_individual_label(individual) { // Update the c string pointer to the one we hold. debug_utils_label.labelName = label_name.c_str(); + // Zero out the next pointer to avoid a dangling pointer + debug_utils_label.next = nullptr; } XrSdkSessionLabelPtr XrSdkSessionLabel::make(const XrDebugUtilsLabelEXT& label_info, bool individual) { @@ -143,7 +145,7 @@ void DebugUtilsData::AddObjectName(uint64_t object_handle, XrObjectType object_t } // We always want to remove the old individual label before we do anything else. -// So, do that in it's own method +// So, do that in its own method void DebugUtilsData::RemoveIndividualLabel(XrSdkSessionLabelList& label_vec) { if (!label_vec.empty() && label_vec.back()->is_individual_label) { label_vec.pop_back(); diff --git a/thirdparty/openxr/src/common/object_info.h b/thirdparty/openxr/src/common/object_info.h index 8e9742b605..247ede0dcc 100644 --- a/thirdparty/openxr/src/common/object_info.h +++ b/thirdparty/openxr/src/common/object_info.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // Copyright (c) 2019 Collabora, Ltd. diff --git a/thirdparty/openxr/src/common/platform_utils.hpp b/thirdparty/openxr/src/common/platform_utils.hpp index 2d870cfea7..219d19789d 100644 --- a/thirdparty/openxr/src/common/platform_utils.hpp +++ b/thirdparty/openxr/src/common/platform_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -37,6 +37,10 @@ #include "common_config.h" #endif // OPENXR_HAVE_COMMON_CONFIG +// Consumers of this file must ensure this function is implemented. For example, the loader will implement this function so that it +// can route messages through the loader's logging system. +void LogPlatformUtilsError(const std::string& message); + // Environment variables #if defined(XR_OS_LINUX) || defined(XR_OS_APPLE) @@ -56,9 +60,11 @@ static inline char* ImplGetSecureEnv(const char* name) { #elif defined(HAVE___SECURE_GETENV) return __secure_getenv(name); #else +// clang-format off #pragma message( \ "Warning: Falling back to non-secure getenv for environmental" \ "lookups! Consider updating to a different libc.") + // clang-format on return ImplGetEnv(name); #endif @@ -79,6 +85,12 @@ static inline std::string PlatformUtilsGetEnv(const char* name) { static inline std::string PlatformUtilsGetSecureEnv(const char* name) { auto str = detail::ImplGetSecureEnv(name); if (str == nullptr) { + str = detail::ImplGetEnv(name); + if (str != nullptr && !std::string(str).empty()) { + LogPlatformUtilsError(std::string("!!! WARNING !!! Environment variable ") + name + + " is being ignored due to running with secure execution. The value '" + str + + "' will NOT be used."); + } return {}; } return str; @@ -131,12 +143,6 @@ static inline bool PlatformGetGlobalRuntimeFileName(uint16_t major_version, std: #elif defined(XR_OS_WINDOWS) -#if !defined(NDEBUG) -inline void LogError(const std::string& error) { OutputDebugStringA(error.c_str()); } -#else -#define LogError(x) -#endif - inline std::wstring utf8_to_wide(const std::string& utf8Text) { if (utf8Text.empty()) { return {}; @@ -145,7 +151,7 @@ inline std::wstring utf8_to_wide(const std::string& utf8Text) { std::wstring wideText; const int wideLength = ::MultiByteToWideChar(CP_UTF8, 0, utf8Text.data(), (int)utf8Text.size(), nullptr, 0); if (wideLength == 0) { - LogError("utf8_to_wide get size error: " + std::to_string(::GetLastError())); + LogPlatformUtilsError("utf8_to_wide get size error: " + std::to_string(::GetLastError())); return {}; } @@ -154,7 +160,7 @@ inline std::wstring utf8_to_wide(const std::string& utf8Text) { wchar_t* wideString = const_cast<wchar_t*>(wideText.data()); // mutable data() only exists in c++17 const int length = ::MultiByteToWideChar(CP_UTF8, 0, utf8Text.data(), (int)utf8Text.size(), wideString, wideLength); if (length != wideLength) { - LogError("utf8_to_wide convert string error: " + std::to_string(::GetLastError())); + LogPlatformUtilsError("utf8_to_wide convert string error: " + std::to_string(::GetLastError())); return {}; } @@ -169,7 +175,7 @@ inline std::string wide_to_utf8(const std::wstring& wideText) { std::string narrowText; int narrowLength = ::WideCharToMultiByte(CP_UTF8, 0, wideText.data(), (int)wideText.size(), nullptr, 0, nullptr, nullptr); if (narrowLength == 0) { - LogError("wide_to_utf8 get size error: " + std::to_string(::GetLastError())); + LogPlatformUtilsError("wide_to_utf8 get size error: " + std::to_string(::GetLastError())); return {}; } @@ -179,7 +185,7 @@ inline std::string wide_to_utf8(const std::wstring& wideText) { const int length = ::WideCharToMultiByte(CP_UTF8, 0, wideText.data(), (int)wideText.size(), narrowString, narrowLength, nullptr, nullptr); if (length != narrowLength) { - LogError("wide_to_utf8 convert string error: " + std::to_string(::GetLastError())); + LogPlatformUtilsError("wide_to_utf8 convert string error: " + std::to_string(::GetLastError())); return {}; } @@ -245,7 +251,7 @@ static inline std::string PlatformUtilsGetEnv(const char* name) { // call if there was enough capacity. Else it returns the required capacity (including null terminator). const DWORD length = ::GetEnvironmentVariableW(wname.c_str(), wValueData, (DWORD)wValue.size()); if ((length == 0) || (length >= wValue.size())) { // If error or the variable increased length between calls... - LogError("GetEnvironmentVariable get value error: " + std::to_string(::GetLastError())); + LogPlatformUtilsError("GetEnvironmentVariable get value error: " + std::to_string(::GetLastError())); return {}; } @@ -256,13 +262,20 @@ static inline std::string PlatformUtilsGetEnv(const char* name) { // Acts the same as PlatformUtilsGetEnv except returns an empty string if IsHighIntegrityLevel. static inline std::string PlatformUtilsGetSecureEnv(const char* name) { + // No secure version for Windows so the below integrity check is needed. + const std::string envValue = PlatformUtilsGetEnv(name); + // Do not allow high integrity processes to act on data that can be controlled by medium integrity processes. if (IsHighIntegrityLevel()) { + if (!envValue.empty()) { + LogPlatformUtilsError(std::string("!!! WARNING !!! Environment variable ") + name + + " is being ignored due to running from an elevated context. The value '" + envValue + + "' will NOT be used."); + } return {}; } - // No secure version for Windows so the above integrity check is needed. - return PlatformUtilsGetEnv(name); + return envValue; } // Sets an environment variable via UTF8 strings. @@ -303,7 +316,7 @@ static inline bool PlatformUtilsSetEnv(const char* /* name */, const char* /* va // Intended to be only used as a fallback on Android, with a more open, "native" technique used in most cases static inline bool PlatformGetGlobalRuntimeFileName(uint16_t major_version, std::string& file_name) { // Prefix for the runtime JSON file name - static const char* rt_dir_prefixes[] = {"/oem", "/vendor", "/system"}; + static const char* rt_dir_prefixes[] = {"/product", "/odm", "/oem", "/vendor", "/system"}; static const std::string rt_filename = "/active_runtime.json"; static const std::string subdir = "/etc/openxr/"; for (const auto prefix : rt_dir_prefixes) { diff --git a/thirdparty/openxr/src/common/stdfs_conditions.h b/thirdparty/openxr/src/common/stdfs_conditions.h index 6dc18cc620..0a551f08cd 100644 --- a/thirdparty/openxr/src/common/stdfs_conditions.h +++ b/thirdparty/openxr/src/common/stdfs_conditions.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/thirdparty/openxr/src/common/unique_asset.h b/thirdparty/openxr/src/common/unique_asset.h index 4929039a03..a8ae8077bc 100644 --- a/thirdparty/openxr/src/common/unique_asset.h +++ b/thirdparty/openxr/src/common/unique_asset.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 OR MIT #pragma once diff --git a/thirdparty/openxr/src/common/vulkan_debug_object_namer.hpp b/thirdparty/openxr/src/common/vulkan_debug_object_namer.hpp new file mode 100644 index 0000000000..451219d20f --- /dev/null +++ b/thirdparty/openxr/src/common/vulkan_debug_object_namer.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2017-2023, The Khronos Group Inc. +// +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +#include <vulkan/vulkan_core.h> +#include <stdexcept> + +/// Utility class for assigning debug names to Vulkan objects we create. +class VulkanDebugObjectNamer { + public: + /// Construct without initializing + VulkanDebugObjectNamer() = default; + + /// Construct and initialize + VulkanDebugObjectNamer(VkInstance instance, VkDevice device) : m_vkDevice{device} { + vkSetDebugUtilsObjectNameEXT = + (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT"); + } + /// Copy constructor + VulkanDebugObjectNamer(const VulkanDebugObjectNamer&) = default; + /// Copy assignment operator + VulkanDebugObjectNamer& operator=(const VulkanDebugObjectNamer&) = default; + + /// Destructor + ~VulkanDebugObjectNamer() { Reset(); } + + /// (Re-) Initialize the namer: takes a valid `VkInstance` and `VkDevice` + void Init(VkInstance instance, VkDevice device) { + Reset(); + *this = VulkanDebugObjectNamer(instance, device); + } + + /// The main operation of the namer: actually set an object name. + /// + /// If the namer is not initialized, this exits silently. + VkResult SetName(VkObjectType objectType, uint64_t objectHandle, const char* pObjectName) const { + if (m_vkDevice == nullptr) { + return VK_SUCCESS; + } + if (vkSetDebugUtilsObjectNameEXT != nullptr) { + VkDebugUtilsObjectNameInfoEXT nameInfo{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, nullptr, objectType, + objectHandle, pObjectName}; + return vkSetDebugUtilsObjectNameEXT(m_vkDevice, &nameInfo); + } + return VK_SUCCESS; + } + + /// De-initialize the namer, forgetting the device and the function pointer loaded from the instance. + void Reset() { + vkSetDebugUtilsObjectNameEXT = nullptr; + m_vkDevice = VK_NULL_HANDLE; + } + + private: + VkDevice m_vkDevice{VK_NULL_HANDLE}; + PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{nullptr}; +}; + +#endif diff --git a/thirdparty/openxr/src/common/xr_dependencies.h b/thirdparty/openxr/src/common/xr_dependencies.h index e34527abc3..5c7bd04774 100644 --- a/thirdparty/openxr/src/common/xr_dependencies.h +++ b/thirdparty/openxr/src/common/xr_dependencies.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2022, The Khronos Group Inc. +// Copyright (c) 2018-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 OR MIT // @@ -46,18 +46,6 @@ #ifdef XR_USE_PLATFORM_XLIB #include <X11/Xlib.h> #include <X11/Xutil.h> - -#ifdef Success -#undef Success -#endif // Success - -#ifdef Always -#undef Always -#endif // Always - -#ifdef None -#undef None -#endif // None #endif // XR_USE_PLATFORM_XLIB #ifdef XR_USE_PLATFORM_XCB @@ -72,7 +60,7 @@ #include <xcb/glx.h> #endif // XR_USE_PLATFORM_XCB #ifdef XR_USE_PLATFORM_MACOS -#include <CL/cl_gl_ext.h> +#include <OpenCL/cl_gl_ext.h> #endif // XR_USE_PLATFORM_MACOS #endif // XR_USE_GRAPHICS_API_OPENGL @@ -87,3 +75,19 @@ #ifdef XR_USE_PLATFORM_WAYLAND #include "wayland-client.h" #endif // XR_USE_PLATFORM_WAYLAND + +#ifdef XR_USE_GRAPHICS_API_OPENGL +#if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) +#ifdef Success +#undef Success +#endif // Success + +#ifdef Always +#undef Always +#endif // Always + +#ifdef None +#undef None +#endif // None +#endif // defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) +#endif // XR_USE_GRAPHICS_API_OPENGL diff --git a/thirdparty/openxr/src/common/xr_linear.h b/thirdparty/openxr/src/common/xr_linear.h index 1f0e803b7a..5b0da645ac 100644 --- a/thirdparty/openxr/src/common/xr_linear.h +++ b/thirdparty/openxr/src/common/xr_linear.h @@ -21,11 +21,6 @@ #ifndef XR_LINEAR_H_ #define XR_LINEAR_H_ -#if defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) || defined(OS_LINUX_WAYLAND) -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma clang diagnostic ignored "-Wunused-function" -#endif - #include <openxr/openxr.h> /* @@ -51,6 +46,7 @@ XrVector2f XrVector3f XrVector4f XrQuaternionf +XrPosef XrMatrix4x4f inline static void XrVector3f_Set(XrVector3f* v, const float value); @@ -64,8 +60,18 @@ inline static void XrVector3f_Scale(XrVector3f* result, const XrVector3f* a, con inline static void XrVector3f_Normalize(XrVector3f* v); inline static float XrVector3f_Length(const XrVector3f* v); +inline static void XrQuaternionf_CreateIdentity(XrQuaternionf* q); +inline static void XrQuaternionf_CreateFromAxisAngle(XrQuaternionf* result, const XrVector3f* axis, const float angleInRadians); inline static void XrQuaternionf_Lerp(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b, const float fraction); -inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b; +inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b); +inline static void XrQuaternionf_Invert(XrQuaternionf* result, const XrQuaternionf* q); +inline static void XrQuaternionf_Normalize(XrQuaternionf* q); +inline static void XrQuaternionf_RotateVector3f(XrVector3f* result, const XrQuaternionf* a, const XrVector3f* v); + +inline static void XrPosef_CreateIdentity(XrPosef* result); +inline static void XrPosef_TransformVector3f(XrVector3f* result, const XrPosef* a, const XrVector3f* v); +inline static void XrPosef_Multiply(XrPosef* result, const XrPosef* a, const XrPosef* b); +inline static void XrPosef_Invert(XrPosef* result, const XrPosef* a); inline static void XrMatrix4x4f_CreateIdentity(XrMatrix4x4f* result); inline static void XrMatrix4x4f_CreateTranslation(XrMatrix4x4f* result, const float x, const float y, const float z); @@ -74,13 +80,13 @@ inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float inline static void XrMatrix4x4f_CreateScale(XrMatrix4x4f* result, const float x, const float y, const float z); inline static void XrMatrix4x4f_CreateTranslationRotationScale(XrMatrix4x4f* result, const XrVector3f* translation, const XrQuaternionf* rotation, const XrVector3f* scale); -inline static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f* result, const float tanAngleLeft, const float tanAngleRight, - const float tanAngleUp, float const tanAngleDown, const float nearZ, - const float farZ); -inline static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f* result, const float fovDegreesLeft, const float fovDegreesRight, - const float fovDegreeUp, const float fovDegreesDown, const float nearZ, - const float farZ); -inline static void XrMatrix4x4f_CreateFromQuaternion(XrMatrix4x4f* result, const XrQuaternionf* src); +inline static void XrMatrix4x4f_CreateFromRigidTransform(XrMatrix4x4f* result, const XrPosef* s); +inline static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f* result, GraphicsAPI graphicsApi, const float tanAngleLeft, + const float tanAngleRight, const float tanAngleUp, float const tanAngleDown, + const float nearZ, const float farZ); +inline static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f* result, GraphicsAPI graphicsApi, const XrFovf fov, + const float nearZ, const float farZ); +inline static void XrMatrix4x4f_CreateFromQuaternion(XrMatrix4x4f* result, const XrQuaternionf* quat); inline static void XrMatrix4x4f_CreateOffsetScaleForBounds(XrMatrix4x4f* result, const XrMatrix4x4f* matrix, const XrVector3f* mins, const XrVector3f* maxs); @@ -207,6 +213,13 @@ inline static void XrVector3f_Normalize(XrVector3f* v) { inline static float XrVector3f_Length(const XrVector3f* v) { return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); } +inline static void XrQuaternionf_CreateIdentity(XrQuaternionf* q) { + q->x = 0.0f; + q->y = 0.0f; + q->z = 0.0f; + q->w = 1.0f; +} + inline static void XrQuaternionf_CreateFromAxisAngle(XrQuaternionf* result, const XrVector3f* axis, const float angleInRadians) { float s = sinf(angleInRadians / 2.0f); float lengthRcp = XrRcpSqrt(axis->x * axis->x + axis->y * axis->y + axis->z * axis->z); @@ -238,6 +251,58 @@ inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuatern result->w = (b->w * a->w) - (b->x * a->x) - (b->y * a->y) - (b->z * a->z); } +inline static void XrQuaternionf_Invert(XrQuaternionf* result, const XrQuaternionf* q) { + result->x = -q->x; + result->y = -q->y; + result->z = -q->z; + result->w = q->w; +} + +inline static void XrQuaternionf_Normalize(XrQuaternionf* q) { + const float lengthRcp = XrRcpSqrt(q->x * q->x + q->y * q->y + q->z * q->z + q->w * q->w); + q->x *= lengthRcp; + q->y *= lengthRcp; + q->z *= lengthRcp; + q->w *= lengthRcp; +} + +inline static void XrQuaternionf_RotateVector3f(XrVector3f* result, const XrQuaternionf* a, const XrVector3f* v) { + XrQuaternionf q = {v->x, v->y, v->z, 0.0f}; + XrQuaternionf aq; + XrQuaternionf_Multiply(&aq, &q, a); + XrQuaternionf aInv; + XrQuaternionf_Invert(&aInv, a); + XrQuaternionf aqaInv; + XrQuaternionf_Multiply(&aqaInv, &aInv, &aq); + + result->x = aqaInv.x; + result->y = aqaInv.y; + result->z = aqaInv.z; +} + +inline static void XrPosef_CreateIdentity(XrPosef* result) { + XrQuaternionf_CreateIdentity(&result->orientation); + XrVector3f_Set(&result->position, 0); +} + +inline static void XrPosef_TransformVector3f(XrVector3f* result, const XrPosef* a, const XrVector3f* v) { + XrVector3f r0; + XrQuaternionf_RotateVector3f(&r0, &a->orientation, v); + XrVector3f_Add(result, &r0, &a->position); +} + +inline static void XrPosef_Multiply(XrPosef* result, const XrPosef* a, const XrPosef* b) { + XrQuaternionf_Multiply(&result->orientation, &b->orientation, &a->orientation); + XrPosef_TransformVector3f(&result->position, a, &b->position); +} + +inline static void XrPosef_Invert(XrPosef* result, const XrPosef* a) { + XrQuaternionf_Invert(&result->orientation, &a->orientation); + XrVector3f aPosNeg; + XrVector3f_Scale(&aPosNeg, &a->position, -1.0f); + XrQuaternionf_RotateVector3f(&result->position, &result->orientation, &aPosNeg); +} + // Use left-multiplication to accumulate transformations. inline static void XrMatrix4x4f_Multiply(XrMatrix4x4f* result, const XrMatrix4x4f* a, const XrMatrix4x4f* b) { result->m[0] = a->m[0] * b->m[0] + a->m[4] * b->m[1] + a->m[8] * b->m[2] + a->m[12] * b->m[3]; @@ -379,23 +444,31 @@ inline static void XrMatrix4x4f_CreateTranslation(XrMatrix4x4f* result, const fl } // Creates a rotation matrix. -// If -Z=forward, +Y=up, +X=right, then degreesX=pitch, degreesY=yaw, degreesZ=roll. -inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float degreesX, const float degreesY, - const float degreesZ) { - const float sinX = sinf(degreesX * (MATH_PI / 180.0f)); - const float cosX = cosf(degreesX * (MATH_PI / 180.0f)); +// If -Z=forward, +Y=up, +X=right, then radiansX=pitch, radiansY=yaw, radiansZ=roll. +inline static void XrMatrix4x4f_CreateRotationRadians(XrMatrix4x4f* result, const float radiansX, const float radiansY, + const float radiansZ) { + const float sinX = sinf(radiansX); + const float cosX = cosf(radiansX); const XrMatrix4x4f rotationX = {{1, 0, 0, 0, 0, cosX, sinX, 0, 0, -sinX, cosX, 0, 0, 0, 0, 1}}; - const float sinY = sinf(degreesY * (MATH_PI / 180.0f)); - const float cosY = cosf(degreesY * (MATH_PI / 180.0f)); + const float sinY = sinf(radiansY); + const float cosY = cosf(radiansY); const XrMatrix4x4f rotationY = {{cosY, 0, -sinY, 0, 0, 1, 0, 0, sinY, 0, cosY, 0, 0, 0, 0, 1}}; - const float sinZ = sinf(degreesZ * (MATH_PI / 180.0f)); - const float cosZ = cosf(degreesZ * (MATH_PI / 180.0f)); + const float sinZ = sinf(radiansZ); + const float cosZ = cosf(radiansZ); const XrMatrix4x4f rotationZ = {{cosZ, sinZ, 0, 0, -sinZ, cosZ, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}}; XrMatrix4x4f rotationXY; XrMatrix4x4f_Multiply(&rotationXY, &rotationY, &rotationX); XrMatrix4x4f_Multiply(result, &rotationZ, &rotationXY); } +// Creates a rotation matrix. +// If -Z=forward, +Y=up, +X=right, then degreesX=pitch, degreesY=yaw, degreesZ=roll. +inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float degreesX, const float degreesY, + const float degreesZ) { + XrMatrix4x4f_CreateRotationRadians(result, degreesX * (MATH_PI / 180.0f), degreesY * (MATH_PI / 180.0f), + degreesZ * (MATH_PI / 180.0f)); +} + // Creates a scale matrix. inline static void XrMatrix4x4f_CreateScale(XrMatrix4x4f* result, const float x, const float y, const float z) { result->m[0] = x; @@ -471,6 +544,11 @@ inline static void XrMatrix4x4f_CreateTranslationRotationScale(XrMatrix4x4f* res XrMatrix4x4f_Multiply(result, &translationMatrix, &combinedMatrix); } +inline static void XrMatrix4x4f_CreateFromRigidTransform(XrMatrix4x4f* result, const XrPosef* s) { + const XrVector3f identityScale = {1.0f, 1.0f, 1.0f}; + XrMatrix4x4f_CreateTranslationRotationScale(result, &s->position, &s->orientation, &identityScale); +} + // Creates a projection matrix based on the specified dimensions. // The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API. // The far plane is placed at infinity if farZ <= nearZ. diff --git a/thirdparty/openxr/src/loader/android_utilities.cpp b/thirdparty/openxr/src/loader/android_utilities.cpp index 59d9a99b74..9a3ad76ce0 100644 --- a/thirdparty/openxr/src/loader/android_utilities.cpp +++ b/thirdparty/openxr/src/loader/android_utilities.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // Copyright (c) 2020-2021, Collabora, Ltd. // // SPDX-License-Identifier: Apache-2.0 OR MIT @@ -19,10 +19,10 @@ #include <vector> #include <android/log.h> -#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, "openxr_loader", __VA_ARGS__) -#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, "openxr_loader", __VA_ARGS__) -#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "openxr_loader", __VA_ARGS__) -#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, "openxr_loader", __VA_ARGS__) +#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, "OpenXR-Loader", __VA_ARGS__) +#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, "OpenXR-Loader", __VA_ARGS__) +#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "OpenXR-Loader", __VA_ARGS__) +#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, "OpenXR-Loader", __VA_ARGS__) namespace openxr_android { using wrap::android::content::ContentUris; diff --git a/thirdparty/openxr/src/loader/android_utilities.h b/thirdparty/openxr/src/loader/android_utilities.h index adb8abaf1f..f66c9bf1d0 100644 --- a/thirdparty/openxr/src/loader/android_utilities.h +++ b/thirdparty/openxr/src/loader/android_utilities.h @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022, The Khronos Group Inc. +// Copyright (c) 2020-2023, The Khronos Group Inc. // Copyright (c) 2020-2021, Collabora, Ltd. // // SPDX-License-Identifier: Apache-2.0 OR MIT diff --git a/thirdparty/openxr/src/loader/api_layer_interface.cpp b/thirdparty/openxr/src/loader/api_layer_interface.cpp index b946e09402..5560c31a52 100644 --- a/thirdparty/openxr/src/loader/api_layer_interface.cpp +++ b/thirdparty/openxr/src/loader/api_layer_interface.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -82,6 +82,12 @@ XrResult ApiLayerInterface::GetApiLayerProperties(const std::string& openxr_comm return result; } + // check for potential overflow before static_cast<uint32_t> + if (manifest_files.size() >= UINT32_MAX) { + LoaderLogger::LogErrorMessage(openxr_command, "ApiLayerInterface::GetApiLayerProperties - too many API layers found"); + return XR_ERROR_RUNTIME_FAILURE; + } + manifest_count = static_cast<uint32_t>(manifest_files.size()); if (nullptr == outgoing_count) { LoaderLogger::LogErrorMessage("xrEnumerateInstanceExtensionProperties", @@ -131,8 +137,8 @@ XrResult ApiLayerInterface::GetInstanceExtensionProperties(const std::string& op } bool found = false; - auto num_files = static_cast<uint32_t>(manifest_files.size()); - for (uint32_t man_file = 0; man_file < num_files; ++man_file) { + size_t num_files = manifest_files.size(); + for (size_t man_file = 0; man_file < num_files; ++man_file) { // If a layer with the provided name exists, get it's instance extension information. if (manifest_files[man_file]->LayerName() == layer_name) { manifest_files[man_file]->GetInstanceExtensionProperties(extension_properties); @@ -172,8 +178,8 @@ XrResult ApiLayerInterface::GetInstanceExtensionProperties(const std::string& op } // Grab the layer instance extensions information - auto num_files = static_cast<uint32_t>(manifest_files.size()); - for (uint32_t man_file = 0; man_file < num_files; ++man_file) { + size_t num_files = manifest_files.size(); + for (size_t man_file = 0; man_file < num_files; ++man_file) { manifest_files[man_file]->GetInstanceExtensionProperties(extension_properties); } } diff --git a/thirdparty/openxr/src/loader/api_layer_interface.hpp b/thirdparty/openxr/src/loader/api_layer_interface.hpp index b93e44584e..98685b0c32 100644 --- a/thirdparty/openxr/src/loader/api_layer_interface.hpp +++ b/thirdparty/openxr/src/loader/api_layer_interface.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/exception_handling.hpp b/thirdparty/openxr/src/loader/exception_handling.hpp index 428dd00279..bc0d9b65e3 100644 --- a/thirdparty/openxr/src/loader/exception_handling.hpp +++ b/thirdparty/openxr/src/loader/exception_handling.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2022, The Khronos Group Inc. +// Copyright (c) 2019-2023, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 OR MIT // diff --git a/thirdparty/openxr/src/loader/loader_core.cpp b/thirdparty/openxr/src/loader/loader_core.cpp index f2bc87d1fa..98d3fa971a 100644 --- a/thirdparty/openxr/src/loader/loader_core.cpp +++ b/thirdparty/openxr/src/loader/loader_core.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/loader_instance.cpp b/thirdparty/openxr/src/loader/loader_instance.cpp index b24c8de53b..badd39193c 100644 --- a/thirdparty/openxr/src/loader/loader_instance.cpp +++ b/thirdparty/openxr/src/loader/loader_instance.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -200,8 +200,8 @@ XrResult LoaderInstance::CreateInstance(PFN_xrGetInstanceProcAddr get_instance_p if (!api_layer_interfaces.empty()) { // Initialize an array of ApiLayerNextInfo structs std::unique_ptr<XrApiLayerNextInfo[]> next_info_list(new XrApiLayerNextInfo[api_layer_interfaces.size()]); - auto ni_index = static_cast<uint32_t>(api_layer_interfaces.size() - 1); - for (uint32_t i = 0; i <= ni_index; i++) { + size_t ni_index = api_layer_interfaces.size() - 1; + for (size_t i = 0; i <= ni_index; i++) { next_info_list[i].structType = XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO; next_info_list[i].structVersion = XR_API_LAYER_NEXT_INFO_STRUCT_VERSION; next_info_list[i].structSize = sizeof(XrApiLayerNextInfo); diff --git a/thirdparty/openxr/src/loader/loader_instance.hpp b/thirdparty/openxr/src/loader/loader_instance.hpp index 1d43ed758d..a0268a855c 100644 --- a/thirdparty/openxr/src/loader/loader_instance.hpp +++ b/thirdparty/openxr/src/loader/loader_instance.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/loader_logger.cpp b/thirdparty/openxr/src/loader/loader_logger.cpp index dba46aa92d..1c8d64f394 100644 --- a/thirdparty/openxr/src/loader/loader_logger.cpp +++ b/thirdparty/openxr/src/loader/loader_logger.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -26,6 +26,9 @@ #include <utility> #include <vector> +// For routing platform_utils.hpp messages into the LoaderLogger. +void LogPlatformUtilsError(const std::string& message) { LoaderLogger::LogErrorMessage("platform_utils", message); } + bool LoaderLogRecorder::LogDebugUtilsMessage(XrDebugUtilsMessageSeverityFlagsEXT /*message_severity*/, XrDebugUtilsMessageTypeFlagsEXT /*message_type*/, const XrDebugUtilsMessengerCallbackDataEXT* /*callback_data*/) { diff --git a/thirdparty/openxr/src/loader/loader_logger.hpp b/thirdparty/openxr/src/loader/loader_logger.hpp index 260ebe354a..d31fac093a 100644 --- a/thirdparty/openxr/src/loader/loader_logger.hpp +++ b/thirdparty/openxr/src/loader/loader_logger.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/loader_logger_recorders.cpp b/thirdparty/openxr/src/loader/loader_logger_recorders.cpp index 7673678c60..32e4687b2f 100644 --- a/thirdparty/openxr/src/loader/loader_logger_recorders.cpp +++ b/thirdparty/openxr/src/loader/loader_logger_recorders.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -160,16 +160,16 @@ bool DebugUtilsLogRecorder::LogMessage(XrLoaderLogMessageSeverityFlagBits messag XrDebugUtilsMessageTypeFlagsEXT utils_type = LoaderLogMessageTypesToDebugUtilsMessageTypes(message_type); // Convert the loader log message into the debug utils log message information - XrDebugUtilsMessengerCallbackDataEXT utils_callback_data = {}; + XrDebugUtilsMessengerCallbackDataEXT utils_callback_data{}; utils_callback_data.type = XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT; utils_callback_data.messageId = callback_data->message_id; utils_callback_data.functionName = callback_data->command_name; utils_callback_data.message = callback_data->message; - std::vector<XrDebugUtilsObjectNameInfoEXT> utils_objects; - utils_objects.resize(callback_data->object_count); + + XrDebugUtilsObjectNameInfoEXT example_utils_info{}; + example_utils_info.type = XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + std::vector<XrDebugUtilsObjectNameInfoEXT> utils_objects(callback_data->object_count, example_utils_info); for (uint8_t object = 0; object < callback_data->object_count; ++object) { - utils_objects[object].type = XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; - utils_objects[object].next = nullptr; utils_objects[object].objectHandle = callback_data->objects[object].handle; utils_objects[object].objectType = callback_data->objects[object].type; utils_objects[object].objectName = callback_data->objects[object].name.c_str(); diff --git a/thirdparty/openxr/src/loader/loader_logger_recorders.hpp b/thirdparty/openxr/src/loader/loader_logger_recorders.hpp index 31e5243c45..7b934202d5 100644 --- a/thirdparty/openxr/src/loader/loader_logger_recorders.hpp +++ b/thirdparty/openxr/src/loader/loader_logger_recorders.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/loader_platform.hpp b/thirdparty/openxr/src/loader/loader_platform.hpp index e2757fffb9..0ea80c05b8 100644 --- a/thirdparty/openxr/src/loader/loader_platform.hpp +++ b/thirdparty/openxr/src/loader/loader_platform.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/manifest_file.cpp b/thirdparty/openxr/src/loader/manifest_file.cpp index 1b0ef07848..99f4e84104 100644 --- a/thirdparty/openxr/src/loader/manifest_file.cpp +++ b/thirdparty/openxr/src/loader/manifest_file.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -27,13 +27,13 @@ #include <openxr/openxr.h> #include <algorithm> +#include <cstdlib> +#include <cstdio> #include <cstring> #include <fstream> #include <memory> #include <sstream> #include <stdexcept> -#include <stdio.h> -#include <stdlib.h> #include <string> #include <unordered_map> #include <utility> @@ -233,6 +233,12 @@ static void ReadDataFilesInSearchPaths(const std::string &override_env_var, cons relative_home_path += relative_path; CopyIncludedPaths(true, home, relative_home_path, search_path); } +#elif defined(XR_OS_ANDROID) + CopyIncludedPaths(true, "/product/etc", relative_path, search_path); + CopyIncludedPaths(true, "/odm/etc", relative_path, search_path); + CopyIncludedPaths(true, "/oem/etc", relative_path, search_path); + CopyIncludedPaths(true, "/vendor/etc", relative_path, search_path); + CopyIncludedPaths(true, "/system/etc", relative_path, search_path); #else (void)relative_path; #endif @@ -447,9 +453,8 @@ static void GetExtensionProperties(const std::vector<ExtensionListing> &extensio if (it != props.end()) { it->extensionVersion = std::max(it->extensionVersion, ext.extension_version); } else { - XrExtensionProperties prop = {}; + XrExtensionProperties prop{}; prop.type = XR_TYPE_EXTENSION_PROPERTIES; - prop.next = nullptr; strncpy(prop.extensionName, ext.name.c_str(), XR_MAX_EXTENSION_NAME_SIZE - 1); prop.extensionName[XR_MAX_EXTENSION_NAME_SIZE - 1] = '\0'; prop.extensionVersion = ext.extension_version; diff --git a/thirdparty/openxr/src/loader/manifest_file.hpp b/thirdparty/openxr/src/loader/manifest_file.hpp index de0aab65c2..46b842c663 100644 --- a/thirdparty/openxr/src/loader/manifest_file.hpp +++ b/thirdparty/openxr/src/loader/manifest_file.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017 Valve Corporation // Copyright (c) 2017 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/runtime_interface.cpp b/thirdparty/openxr/src/loader/runtime_interface.cpp index 0f081ff9b2..d9ab86bb58 100644 --- a/thirdparty/openxr/src/loader/runtime_interface.cpp +++ b/thirdparty/openxr/src/loader/runtime_interface.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -430,12 +430,10 @@ void RuntimeInterface::GetInstanceExtensionProperties(std::vector<XrExtensionPro // Get the count from the runtime rt_xrEnumerateInstanceExtensionProperties(nullptr, count, &count_output, nullptr); if (count_output > 0) { - runtime_extension_properties.resize(count_output); + XrExtensionProperties example_properties{}; + example_properties.type = XR_TYPE_EXTENSION_PROPERTIES; + runtime_extension_properties.resize(count_output, example_properties); count = count_output; - for (XrExtensionProperties& ext_prop : runtime_extension_properties) { - ext_prop.type = XR_TYPE_EXTENSION_PROPERTIES; - ext_prop.next = nullptr; - } rt_xrEnumerateInstanceExtensionProperties(nullptr, count, &count_output, runtime_extension_properties.data()); } size_t ext_count = runtime_extension_properties.size(); diff --git a/thirdparty/openxr/src/loader/runtime_interface.hpp b/thirdparty/openxr/src/loader/runtime_interface.hpp index fa53ee03f2..8d55ec674a 100644 --- a/thirdparty/openxr/src/loader/runtime_interface.hpp +++ b/thirdparty/openxr/src/loader/runtime_interface.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/xr_generated_loader.cpp b/thirdparty/openxr/src/loader/xr_generated_loader.cpp index 2ce323e51f..e7767fd30a 100644 --- a/thirdparty/openxr/src/loader/xr_generated_loader.cpp +++ b/thirdparty/openxr/src/loader/xr_generated_loader.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // SPDX-License-Identifier: Apache-2.0 OR MIT @@ -6,7 +6,7 @@ // See loader_source_generator.py for modifications // ************************************************************ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/loader/xr_generated_loader.hpp b/thirdparty/openxr/src/loader/xr_generated_loader.hpp index 482cf1e83e..e28e35bbcf 100644 --- a/thirdparty/openxr/src/loader/xr_generated_loader.hpp +++ b/thirdparty/openxr/src/loader/xr_generated_loader.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // SPDX-License-Identifier: Apache-2.0 OR MIT @@ -6,7 +6,7 @@ // See loader_source_generator.py for modifications // ************************************************************ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // diff --git a/thirdparty/openxr/src/xr_generated_dispatch_table.c b/thirdparty/openxr/src/xr_generated_dispatch_table.c index 094f9fbbda..302bed31f5 100644 --- a/thirdparty/openxr/src/xr_generated_dispatch_table.c +++ b/thirdparty/openxr/src/xr_generated_dispatch_table.c @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // SPDX-License-Identifier: Apache-2.0 OR MIT @@ -6,7 +6,7 @@ // See utility_source_generator.py for modifications // ************************************************************ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -27,6 +27,7 @@ // Author: Mark Young <marky@lunarg.com> // +#include <time.h> #include "xr_generated_dispatch_table.h" #include "xr_dependencies.h" #include <openxr/openxr.h> @@ -236,6 +237,12 @@ void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, (get_inst_proc_addr(instance, "xrUpdateSwapchainFB", (PFN_xrVoidFunction*)&table->UpdateSwapchainFB)); (get_inst_proc_addr(instance, "xrGetSwapchainStateFB", (PFN_xrVoidFunction*)&table->GetSwapchainStateFB)); + // ---- XR_FB_body_tracking extension commands + (get_inst_proc_addr(instance, "xrCreateBodyTrackerFB", (PFN_xrVoidFunction*)&table->CreateBodyTrackerFB)); + (get_inst_proc_addr(instance, "xrDestroyBodyTrackerFB", (PFN_xrVoidFunction*)&table->DestroyBodyTrackerFB)); + (get_inst_proc_addr(instance, "xrLocateBodyJointsFB", (PFN_xrVoidFunction*)&table->LocateBodyJointsFB)); + (get_inst_proc_addr(instance, "xrGetBodySkeletonFB", (PFN_xrVoidFunction*)&table->GetBodySkeletonFB)); + // ---- XR_MSFT_scene_understanding extension commands (get_inst_proc_addr(instance, "xrEnumerateSceneComputeFeaturesMSFT", (PFN_xrVoidFunction*)&table->EnumerateSceneComputeFeaturesMSFT)); (get_inst_proc_addr(instance, "xrCreateSceneObserverMSFT", (PFN_xrVoidFunction*)&table->CreateSceneObserverMSFT)); @@ -329,6 +336,11 @@ void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, // ---- XR_VARJO_view_offset extension commands (get_inst_proc_addr(instance, "xrSetViewOffsetVARJO", (PFN_xrVoidFunction*)&table->SetViewOffsetVARJO)); + // ---- XR_ML_compat extension commands +#if defined(XR_USE_PLATFORM_ML) + (get_inst_proc_addr(instance, "xrCreateSpaceFromCoordinateFrameUIDML", (PFN_xrVoidFunction*)&table->CreateSpaceFromCoordinateFrameUIDML)); +#endif // defined(XR_USE_PLATFORM_ML) + // ---- XR_MSFT_spatial_anchor_persistence extension commands (get_inst_proc_addr(instance, "xrCreateSpatialAnchorStoreConnectionMSFT", (PFN_xrVoidFunction*)&table->CreateSpatialAnchorStoreConnectionMSFT)); (get_inst_proc_addr(instance, "xrDestroySpatialAnchorStoreConnectionMSFT", (PFN_xrVoidFunction*)&table->DestroySpatialAnchorStoreConnectionMSFT)); @@ -354,6 +366,9 @@ void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, (get_inst_proc_addr(instance, "xrGetAudioInputDeviceGuidOculus", (PFN_xrVoidFunction*)&table->GetAudioInputDeviceGuidOculus)); #endif // defined(XR_USE_PLATFORM_WIN32) + // ---- XR_FB_spatial_entity_sharing extension commands + (get_inst_proc_addr(instance, "xrShareSpacesFB", (PFN_xrVoidFunction*)&table->ShareSpacesFB)); + // ---- XR_FB_scene extension commands (get_inst_proc_addr(instance, "xrGetSpaceBoundingBox2DFB", (PFN_xrVoidFunction*)&table->GetSpaceBoundingBox2DFB)); (get_inst_proc_addr(instance, "xrGetSpaceBoundingBox3DFB", (PFN_xrVoidFunction*)&table->GetSpaceBoundingBox3DFB)); @@ -364,24 +379,86 @@ void GeneratedXrPopulateDispatchTable(struct XrGeneratedDispatchTable *table, // ---- XR_ALMALENCE_digital_lens_control extension commands (get_inst_proc_addr(instance, "xrSetDigitalLensControlALMALENCE", (PFN_xrVoidFunction*)&table->SetDigitalLensControlALMALENCE)); + // ---- XR_FB_scene_capture extension commands + (get_inst_proc_addr(instance, "xrRequestSceneCaptureFB", (PFN_xrVoidFunction*)&table->RequestSceneCaptureFB)); + // ---- XR_FB_spatial_entity_container extension commands (get_inst_proc_addr(instance, "xrGetSpaceContainerFB", (PFN_xrVoidFunction*)&table->GetSpaceContainerFB)); + // ---- XR_META_foveation_eye_tracked extension commands + (get_inst_proc_addr(instance, "xrGetFoveationEyeTrackedStateMETA", (PFN_xrVoidFunction*)&table->GetFoveationEyeTrackedStateMETA)); + + // ---- XR_FB_face_tracking extension commands + (get_inst_proc_addr(instance, "xrCreateFaceTrackerFB", (PFN_xrVoidFunction*)&table->CreateFaceTrackerFB)); + (get_inst_proc_addr(instance, "xrDestroyFaceTrackerFB", (PFN_xrVoidFunction*)&table->DestroyFaceTrackerFB)); + (get_inst_proc_addr(instance, "xrGetFaceExpressionWeightsFB", (PFN_xrVoidFunction*)&table->GetFaceExpressionWeightsFB)); + + // ---- XR_FB_eye_tracking_social extension commands + (get_inst_proc_addr(instance, "xrCreateEyeTrackerFB", (PFN_xrVoidFunction*)&table->CreateEyeTrackerFB)); + (get_inst_proc_addr(instance, "xrDestroyEyeTrackerFB", (PFN_xrVoidFunction*)&table->DestroyEyeTrackerFB)); + (get_inst_proc_addr(instance, "xrGetEyeGazesFB", (PFN_xrVoidFunction*)&table->GetEyeGazesFB)); + // ---- XR_FB_passthrough_keyboard_hands extension commands (get_inst_proc_addr(instance, "xrPassthroughLayerSetKeyboardHandsIntensityFB", (PFN_xrVoidFunction*)&table->PassthroughLayerSetKeyboardHandsIntensityFB)); + // ---- XR_FB_haptic_pcm extension commands + (get_inst_proc_addr(instance, "xrGetDeviceSampleRateFB", (PFN_xrVoidFunction*)&table->GetDeviceSampleRateFB)); + + // ---- XR_META_virtual_keyboard extension commands + (get_inst_proc_addr(instance, "xrCreateVirtualKeyboardMETA", (PFN_xrVoidFunction*)&table->CreateVirtualKeyboardMETA)); + (get_inst_proc_addr(instance, "xrDestroyVirtualKeyboardMETA", (PFN_xrVoidFunction*)&table->DestroyVirtualKeyboardMETA)); + (get_inst_proc_addr(instance, "xrCreateVirtualKeyboardSpaceMETA", (PFN_xrVoidFunction*)&table->CreateVirtualKeyboardSpaceMETA)); + (get_inst_proc_addr(instance, "xrSuggestVirtualKeyboardLocationMETA", (PFN_xrVoidFunction*)&table->SuggestVirtualKeyboardLocationMETA)); + (get_inst_proc_addr(instance, "xrGetVirtualKeyboardScaleMETA", (PFN_xrVoidFunction*)&table->GetVirtualKeyboardScaleMETA)); + (get_inst_proc_addr(instance, "xrSetVirtualKeyboardModelVisibilityMETA", (PFN_xrVoidFunction*)&table->SetVirtualKeyboardModelVisibilityMETA)); + (get_inst_proc_addr(instance, "xrGetVirtualKeyboardModelAnimationStatesMETA", (PFN_xrVoidFunction*)&table->GetVirtualKeyboardModelAnimationStatesMETA)); + (get_inst_proc_addr(instance, "xrGetVirtualKeyboardDirtyTexturesMETA", (PFN_xrVoidFunction*)&table->GetVirtualKeyboardDirtyTexturesMETA)); + (get_inst_proc_addr(instance, "xrGetVirtualKeyboardTextureDataMETA", (PFN_xrVoidFunction*)&table->GetVirtualKeyboardTextureDataMETA)); + (get_inst_proc_addr(instance, "xrSendVirtualKeyboardInputMETA", (PFN_xrVoidFunction*)&table->SendVirtualKeyboardInputMETA)); + (get_inst_proc_addr(instance, "xrChangeVirtualKeyboardTextContextMETA", (PFN_xrVoidFunction*)&table->ChangeVirtualKeyboardTextContextMETA)); + + // ---- XR_OCULUS_external_camera extension commands + (get_inst_proc_addr(instance, "xrEnumerateExternalCamerasOCULUS", (PFN_xrVoidFunction*)&table->EnumerateExternalCamerasOCULUS)); + // ---- XR_META_performance_metrics extension commands (get_inst_proc_addr(instance, "xrEnumeratePerformanceMetricsCounterPathsMETA", (PFN_xrVoidFunction*)&table->EnumeratePerformanceMetricsCounterPathsMETA)); (get_inst_proc_addr(instance, "xrSetPerformanceMetricsStateMETA", (PFN_xrVoidFunction*)&table->SetPerformanceMetricsStateMETA)); (get_inst_proc_addr(instance, "xrGetPerformanceMetricsStateMETA", (PFN_xrVoidFunction*)&table->GetPerformanceMetricsStateMETA)); (get_inst_proc_addr(instance, "xrQueryPerformanceMetricsCounterMETA", (PFN_xrVoidFunction*)&table->QueryPerformanceMetricsCounterMETA)); + // ---- XR_FB_spatial_entity_storage_batch extension commands + (get_inst_proc_addr(instance, "xrSaveSpaceListFB", (PFN_xrVoidFunction*)&table->SaveSpaceListFB)); + + // ---- XR_FB_spatial_entity_user extension commands + (get_inst_proc_addr(instance, "xrCreateSpaceUserFB", (PFN_xrVoidFunction*)&table->CreateSpaceUserFB)); + (get_inst_proc_addr(instance, "xrGetSpaceUserIdFB", (PFN_xrVoidFunction*)&table->GetSpaceUserIdFB)); + (get_inst_proc_addr(instance, "xrDestroySpaceUserFB", (PFN_xrVoidFunction*)&table->DestroySpaceUserFB)); + + // ---- XR_META_passthrough_color_lut extension commands + (get_inst_proc_addr(instance, "xrCreatePassthroughColorLutMETA", (PFN_xrVoidFunction*)&table->CreatePassthroughColorLutMETA)); + (get_inst_proc_addr(instance, "xrDestroyPassthroughColorLutMETA", (PFN_xrVoidFunction*)&table->DestroyPassthroughColorLutMETA)); + (get_inst_proc_addr(instance, "xrUpdatePassthroughColorLutMETA", (PFN_xrVoidFunction*)&table->UpdatePassthroughColorLutMETA)); + + // ---- XR_QCOM_tracking_optimization_settings extension commands + (get_inst_proc_addr(instance, "xrSetTrackingOptimizationSettingsHintQCOM", (PFN_xrVoidFunction*)&table->SetTrackingOptimizationSettingsHintQCOM)); + // ---- XR_HTC_passthrough extension commands (get_inst_proc_addr(instance, "xrCreatePassthroughHTC", (PFN_xrVoidFunction*)&table->CreatePassthroughHTC)); (get_inst_proc_addr(instance, "xrDestroyPassthroughHTC", (PFN_xrVoidFunction*)&table->DestroyPassthroughHTC)); // ---- XR_HTC_foveation extension commands (get_inst_proc_addr(instance, "xrApplyFoveationHTC", (PFN_xrVoidFunction*)&table->ApplyFoveationHTC)); + + // ---- XR_MNDX_force_feedback_curl extension commands + (get_inst_proc_addr(instance, "xrApplyForceFeedbackCurlMNDX", (PFN_xrVoidFunction*)&table->ApplyForceFeedbackCurlMNDX)); + + // ---- XR_EXT_plane_detection extension commands + (get_inst_proc_addr(instance, "xrCreatePlaneDetectorEXT", (PFN_xrVoidFunction*)&table->CreatePlaneDetectorEXT)); + (get_inst_proc_addr(instance, "xrDestroyPlaneDetectorEXT", (PFN_xrVoidFunction*)&table->DestroyPlaneDetectorEXT)); + (get_inst_proc_addr(instance, "xrBeginPlaneDetectionEXT", (PFN_xrVoidFunction*)&table->BeginPlaneDetectionEXT)); + (get_inst_proc_addr(instance, "xrGetPlaneDetectionStateEXT", (PFN_xrVoidFunction*)&table->GetPlaneDetectionStateEXT)); + (get_inst_proc_addr(instance, "xrGetPlaneDetectionsEXT", (PFN_xrVoidFunction*)&table->GetPlaneDetectionsEXT)); + (get_inst_proc_addr(instance, "xrGetPlanePolygonBufferEXT", (PFN_xrVoidFunction*)&table->GetPlanePolygonBufferEXT)); } diff --git a/thirdparty/openxr/src/xr_generated_dispatch_table.h b/thirdparty/openxr/src/xr_generated_dispatch_table.h index 93d07a149e..b6e17f98d4 100644 --- a/thirdparty/openxr/src/xr_generated_dispatch_table.h +++ b/thirdparty/openxr/src/xr_generated_dispatch_table.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // SPDX-License-Identifier: Apache-2.0 OR MIT @@ -6,7 +6,7 @@ // See utility_source_generator.py for modifications // ************************************************************ -// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2023, The Khronos Group Inc. // Copyright (c) 2017-2019 Valve Corporation // Copyright (c) 2017-2019 LunarG, Inc. // @@ -239,6 +239,12 @@ struct XrGeneratedDispatchTable { PFN_xrUpdateSwapchainFB UpdateSwapchainFB; PFN_xrGetSwapchainStateFB GetSwapchainStateFB; + // ---- XR_FB_body_tracking extension commands + PFN_xrCreateBodyTrackerFB CreateBodyTrackerFB; + PFN_xrDestroyBodyTrackerFB DestroyBodyTrackerFB; + PFN_xrLocateBodyJointsFB LocateBodyJointsFB; + PFN_xrGetBodySkeletonFB GetBodySkeletonFB; + // ---- XR_MSFT_scene_understanding extension commands PFN_xrEnumerateSceneComputeFeaturesMSFT EnumerateSceneComputeFeaturesMSFT; PFN_xrCreateSceneObserverMSFT CreateSceneObserverMSFT; @@ -332,6 +338,11 @@ struct XrGeneratedDispatchTable { // ---- XR_VARJO_view_offset extension commands PFN_xrSetViewOffsetVARJO SetViewOffsetVARJO; + // ---- XR_ML_compat extension commands +#if defined(XR_USE_PLATFORM_ML) + PFN_xrCreateSpaceFromCoordinateFrameUIDML CreateSpaceFromCoordinateFrameUIDML; +#endif // defined(XR_USE_PLATFORM_ML) + // ---- XR_MSFT_spatial_anchor_persistence extension commands PFN_xrCreateSpatialAnchorStoreConnectionMSFT CreateSpatialAnchorStoreConnectionMSFT; PFN_xrDestroySpatialAnchorStoreConnectionMSFT DestroySpatialAnchorStoreConnectionMSFT; @@ -357,6 +368,9 @@ struct XrGeneratedDispatchTable { PFN_xrGetAudioInputDeviceGuidOculus GetAudioInputDeviceGuidOculus; #endif // defined(XR_USE_PLATFORM_WIN32) + // ---- XR_FB_spatial_entity_sharing extension commands + PFN_xrShareSpacesFB ShareSpacesFB; + // ---- XR_FB_scene extension commands PFN_xrGetSpaceBoundingBox2DFB GetSpaceBoundingBox2DFB; PFN_xrGetSpaceBoundingBox3DFB GetSpaceBoundingBox3DFB; @@ -367,24 +381,86 @@ struct XrGeneratedDispatchTable { // ---- XR_ALMALENCE_digital_lens_control extension commands PFN_xrSetDigitalLensControlALMALENCE SetDigitalLensControlALMALENCE; + // ---- XR_FB_scene_capture extension commands + PFN_xrRequestSceneCaptureFB RequestSceneCaptureFB; + // ---- XR_FB_spatial_entity_container extension commands PFN_xrGetSpaceContainerFB GetSpaceContainerFB; + // ---- XR_META_foveation_eye_tracked extension commands + PFN_xrGetFoveationEyeTrackedStateMETA GetFoveationEyeTrackedStateMETA; + + // ---- XR_FB_face_tracking extension commands + PFN_xrCreateFaceTrackerFB CreateFaceTrackerFB; + PFN_xrDestroyFaceTrackerFB DestroyFaceTrackerFB; + PFN_xrGetFaceExpressionWeightsFB GetFaceExpressionWeightsFB; + + // ---- XR_FB_eye_tracking_social extension commands + PFN_xrCreateEyeTrackerFB CreateEyeTrackerFB; + PFN_xrDestroyEyeTrackerFB DestroyEyeTrackerFB; + PFN_xrGetEyeGazesFB GetEyeGazesFB; + // ---- XR_FB_passthrough_keyboard_hands extension commands PFN_xrPassthroughLayerSetKeyboardHandsIntensityFB PassthroughLayerSetKeyboardHandsIntensityFB; + // ---- XR_FB_haptic_pcm extension commands + PFN_xrGetDeviceSampleRateFB GetDeviceSampleRateFB; + + // ---- XR_META_virtual_keyboard extension commands + PFN_xrCreateVirtualKeyboardMETA CreateVirtualKeyboardMETA; + PFN_xrDestroyVirtualKeyboardMETA DestroyVirtualKeyboardMETA; + PFN_xrCreateVirtualKeyboardSpaceMETA CreateVirtualKeyboardSpaceMETA; + PFN_xrSuggestVirtualKeyboardLocationMETA SuggestVirtualKeyboardLocationMETA; + PFN_xrGetVirtualKeyboardScaleMETA GetVirtualKeyboardScaleMETA; + PFN_xrSetVirtualKeyboardModelVisibilityMETA SetVirtualKeyboardModelVisibilityMETA; + PFN_xrGetVirtualKeyboardModelAnimationStatesMETA GetVirtualKeyboardModelAnimationStatesMETA; + PFN_xrGetVirtualKeyboardDirtyTexturesMETA GetVirtualKeyboardDirtyTexturesMETA; + PFN_xrGetVirtualKeyboardTextureDataMETA GetVirtualKeyboardTextureDataMETA; + PFN_xrSendVirtualKeyboardInputMETA SendVirtualKeyboardInputMETA; + PFN_xrChangeVirtualKeyboardTextContextMETA ChangeVirtualKeyboardTextContextMETA; + + // ---- XR_OCULUS_external_camera extension commands + PFN_xrEnumerateExternalCamerasOCULUS EnumerateExternalCamerasOCULUS; + // ---- XR_META_performance_metrics extension commands PFN_xrEnumeratePerformanceMetricsCounterPathsMETA EnumeratePerformanceMetricsCounterPathsMETA; PFN_xrSetPerformanceMetricsStateMETA SetPerformanceMetricsStateMETA; PFN_xrGetPerformanceMetricsStateMETA GetPerformanceMetricsStateMETA; PFN_xrQueryPerformanceMetricsCounterMETA QueryPerformanceMetricsCounterMETA; + // ---- XR_FB_spatial_entity_storage_batch extension commands + PFN_xrSaveSpaceListFB SaveSpaceListFB; + + // ---- XR_FB_spatial_entity_user extension commands + PFN_xrCreateSpaceUserFB CreateSpaceUserFB; + PFN_xrGetSpaceUserIdFB GetSpaceUserIdFB; + PFN_xrDestroySpaceUserFB DestroySpaceUserFB; + + // ---- XR_META_passthrough_color_lut extension commands + PFN_xrCreatePassthroughColorLutMETA CreatePassthroughColorLutMETA; + PFN_xrDestroyPassthroughColorLutMETA DestroyPassthroughColorLutMETA; + PFN_xrUpdatePassthroughColorLutMETA UpdatePassthroughColorLutMETA; + + // ---- XR_QCOM_tracking_optimization_settings extension commands + PFN_xrSetTrackingOptimizationSettingsHintQCOM SetTrackingOptimizationSettingsHintQCOM; + // ---- XR_HTC_passthrough extension commands PFN_xrCreatePassthroughHTC CreatePassthroughHTC; PFN_xrDestroyPassthroughHTC DestroyPassthroughHTC; // ---- XR_HTC_foveation extension commands PFN_xrApplyFoveationHTC ApplyFoveationHTC; + + // ---- XR_MNDX_force_feedback_curl extension commands + PFN_xrApplyForceFeedbackCurlMNDX ApplyForceFeedbackCurlMNDX; + + // ---- XR_EXT_plane_detection extension commands + PFN_xrCreatePlaneDetectorEXT CreatePlaneDetectorEXT; + PFN_xrDestroyPlaneDetectorEXT DestroyPlaneDetectorEXT; + PFN_xrBeginPlaneDetectionEXT BeginPlaneDetectionEXT; + PFN_xrGetPlaneDetectionStateEXT GetPlaneDetectionStateEXT; + PFN_xrGetPlaneDetectionsEXT GetPlaneDetectionsEXT; + PFN_xrGetPlanePolygonBufferEXT GetPlanePolygonBufferEXT; }; diff --git a/thirdparty/rvo2/rvo2_2d/Agent2d.cc b/thirdparty/rvo2/rvo2_2d/Agent2d.cc deleted file mode 100644 index 63471d52a0..0000000000 --- a/thirdparty/rvo2/rvo2_2d/Agent2d.cc +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Agent2d.cpp - * RVO2 Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -/** - * @file Agent2d.cpp - * @brief Defines the Agent2D class. - */ - -#include "Agent2d.h" - -#include <algorithm> -#include <cmath> -#include <limits> - -#include "KdTree2d.h" -#include "Obstacle2d.h" - -namespace RVO2D { -namespace { -/** - * @relates Agent2D - * @brief Solves a one-dimensional linear program on a specified line - * subject to linear constraints defined by lines and a circular - * constraint. - * @param[in] lines Lines defining the linear constraints. - * @param[in] lineNo The specified line constraint. - * @param[in] radius The radius of the circular constraint. - * @param[in] optVelocity The optimization velocity. - * @param[in] directionOpt True if the direction should be optimized. - * @param[in, out] result A reference to the result of the linear program. - * @return True if successful. - */ -bool linearProgram1(const std::vector<Line> &lines, std::size_t lineNo, - float radius, const Vector2 &optVelocity, bool directionOpt, - Vector2 &result) { /* NOLINT(runtime/references) */ - const float dotProduct = lines[lineNo].point * lines[lineNo].direction; - const float discriminant = - dotProduct * dotProduct + radius * radius - absSq(lines[lineNo].point); - - if (discriminant < 0.0F) { - /* Max speed circle fully invalidates line lineNo. */ - return false; - } - - const float sqrtDiscriminant = std::sqrt(discriminant); - float tLeft = -dotProduct - sqrtDiscriminant; - float tRight = -dotProduct + sqrtDiscriminant; - - for (std::size_t i = 0U; i < lineNo; ++i) { - const float denominator = det(lines[lineNo].direction, lines[i].direction); - const float numerator = - det(lines[i].direction, lines[lineNo].point - lines[i].point); - - if (std::fabs(denominator) <= RVO2D_EPSILON) { - /* Lines lineNo and i are (almost) parallel. */ - if (numerator < 0.0F) { - return false; - } - - continue; - } - - const float t = numerator / denominator; - - if (denominator >= 0.0F) { - /* Line i bounds line lineNo on the right. */ - tRight = std::min(tRight, t); - } else { - /* Line i bounds line lineNo on the left. */ - tLeft = std::max(tLeft, t); - } - - if (tLeft > tRight) { - return false; - } - } - - if (directionOpt) { - /* Optimize direction. */ - if (optVelocity * lines[lineNo].direction > 0.0F) { - /* Take right extreme. */ - result = lines[lineNo].point + tRight * lines[lineNo].direction; - } else { - /* Take left extreme. */ - result = lines[lineNo].point + tLeft * lines[lineNo].direction; - } - } else { - /* Optimize closest point. */ - const float t = - lines[lineNo].direction * (optVelocity - lines[lineNo].point); - - if (t < tLeft) { - result = lines[lineNo].point + tLeft * lines[lineNo].direction; - } else if (t > tRight) { - result = lines[lineNo].point + tRight * lines[lineNo].direction; - } else { - result = lines[lineNo].point + t * lines[lineNo].direction; - } - } - - return true; -} - -/** - * @relates Agent2D - * @brief Solves a two-dimensional linear program subject to linear - * constraints defined by lines and a circular constraint. - * @param[in] lines Lines defining the linear constraints. - * @param[in] radius The radius of the circular constraint. - * @param[in] optVelocity The optimization velocity. - * @param[in] directionOpt True if the direction should be optimized. - * @param[in, out] result A reference to the result of the linear program. - * @return The number of the line it fails on, and the number of lines - * if successful. - */ -std::size_t linearProgram2(const std::vector<Line> &lines, float radius, - const Vector2 &optVelocity, bool directionOpt, - Vector2 &result) { /* NOLINT(runtime/references) */ - if (directionOpt) { - /* Optimize direction. Note that the optimization velocity is of unit length - * in this case. - */ - result = optVelocity * radius; - } else if (absSq(optVelocity) > radius * radius) { - /* Optimize closest point and outside circle. */ - result = normalize(optVelocity) * radius; - } else { - /* Optimize closest point and inside circle. */ - result = optVelocity; - } - - for (std::size_t i = 0U; i < lines.size(); ++i) { - if (det(lines[i].direction, lines[i].point - result) > 0.0F) { - /* Result does not satisfy constraint i. Compute new optimal result. */ - const Vector2 tempResult = result; - - if (!linearProgram1(lines, i, radius, optVelocity, directionOpt, - result)) { - result = tempResult; - - return i; - } - } - } - - return lines.size(); -} - -/** - * @relates Agent2D - * @brief Solves a two-dimensional linear program subject to linear - * constraints defined by lines and a circular constraint. - * @param[in] lines Lines defining the linear constraints. - * @param[in] numObstLines Count of obstacle lines. - * @param[in] beginLine The line on which the 2-d linear program failed. - * @param[in] radius The radius of the circular constraint. - * @param[in, out] result A reference to the result of the linear program. - */ -void linearProgram3(const std::vector<Line> &lines, std::size_t numObstLines, - std::size_t beginLine, float radius, - Vector2 &result) { /* NOLINT(runtime/references) */ - float distance = 0.0F; - - for (std::size_t i = beginLine; i < lines.size(); ++i) { - if (det(lines[i].direction, lines[i].point - result) > distance) { - /* Result does not satisfy constraint of line i. */ - std::vector<Line> projLines( - lines.begin(), - lines.begin() + static_cast<std::ptrdiff_t>(numObstLines)); - - for (std::size_t j = numObstLines; j < i; ++j) { - Line line; - - const float determinant = det(lines[i].direction, lines[j].direction); - - if (std::fabs(determinant) <= RVO2D_EPSILON) { - /* Line i and line j are parallel. */ - if (lines[i].direction * lines[j].direction > 0.0F) { - /* Line i and line j point in the same direction. */ - continue; - } - - /* Line i and line j point in opposite direction. */ - line.point = 0.5F * (lines[i].point + lines[j].point); - } else { - line.point = lines[i].point + (det(lines[j].direction, - lines[i].point - lines[j].point) / - determinant) * - lines[i].direction; - } - - line.direction = normalize(lines[j].direction - lines[i].direction); - projLines.push_back(line); - } - - const Vector2 tempResult = result; - - if (linearProgram2( - projLines, radius, - Vector2(-lines[i].direction.y(), lines[i].direction.x()), true, - result) < projLines.size()) { - /* This should in principle not happen. The result is by definition - * already in the feasible region of this linear program. If it fails, - * it is due to small floating point error, and the current result is - * kept. */ - result = tempResult; - } - - distance = det(lines[i].direction, lines[i].point - result); - } - } -} -} /* namespace */ - -Agent2D::Agent2D() - : id_(0U), - maxNeighbors_(0U), - maxSpeed_(0.0F), - neighborDist_(0.0F), - radius_(0.0F), - timeHorizon_(0.0F), - timeHorizonObst_(0.0F) {} - -Agent2D::~Agent2D() {} - -void Agent2D::computeNeighbors(const KdTree2D *kdTree) { - obstacleNeighbors_.clear(); - const float range = timeHorizonObst_ * maxSpeed_ + radius_; - kdTree->computeObstacleNeighbors(this, range * range); - - agentNeighbors_.clear(); - - if (maxNeighbors_ > 0U) { - float rangeSq = neighborDist_ * neighborDist_; - kdTree->computeAgentNeighbors(this, rangeSq); - } -} - -/* Search for the best new velocity. */ -void Agent2D::computeNewVelocity(float timeStep) { - orcaLines_.clear(); - - const float invTimeHorizonObst = 1.0F / timeHorizonObst_; - - /* Create obstacle ORCA lines. */ - for (std::size_t i = 0U; i < obstacleNeighbors_.size(); ++i) { - const Obstacle2D *obstacle1 = obstacleNeighbors_[i].second; - const Obstacle2D *obstacle2 = obstacle1->next_; - - const Vector2 relativePosition1 = obstacle1->point_ - position_; - const Vector2 relativePosition2 = obstacle2->point_ - position_; - - /* Check if velocity obstacle of obstacle is already taken care of by - * previously constructed obstacle ORCA lines. */ - bool alreadyCovered = false; - - for (std::size_t j = 0U; j < orcaLines_.size(); ++j) { - if (det(invTimeHorizonObst * relativePosition1 - orcaLines_[j].point, - orcaLines_[j].direction) - - invTimeHorizonObst * radius_ >= - -RVO2D_EPSILON && - det(invTimeHorizonObst * relativePosition2 - orcaLines_[j].point, - orcaLines_[j].direction) - - invTimeHorizonObst * radius_ >= - -RVO2D_EPSILON) { - alreadyCovered = true; - break; - } - } - - if (alreadyCovered) { - continue; - } - - /* Not yet covered. Check for collisions. */ - const float distSq1 = absSq(relativePosition1); - const float distSq2 = absSq(relativePosition2); - - const float radiusSq = radius_ * radius_; - - const Vector2 obstacleVector = obstacle2->point_ - obstacle1->point_; - const float s = - (-relativePosition1 * obstacleVector) / absSq(obstacleVector); - const float distSqLine = absSq(-relativePosition1 - s * obstacleVector); - - Line line; - - if (s < 0.0F && distSq1 <= radiusSq) { - /* Collision with left vertex. Ignore if non-convex. */ - if (obstacle1->isConvex_) { - line.point = Vector2(0.0F, 0.0F); - line.direction = - normalize(Vector2(-relativePosition1.y(), relativePosition1.x())); - orcaLines_.push_back(line); - } - - continue; - } - - if (s > 1.0F && distSq2 <= radiusSq) { - /* Collision with right vertex. Ignore if non-convex or if it will be - * taken care of by neighoring obstace */ - if (obstacle2->isConvex_ && - det(relativePosition2, obstacle2->direction_) >= 0.0F) { - line.point = Vector2(0.0F, 0.0F); - line.direction = - normalize(Vector2(-relativePosition2.y(), relativePosition2.x())); - orcaLines_.push_back(line); - } - - continue; - } - - if (s >= 0.0F && s <= 1.0F && distSqLine <= radiusSq) { - /* Collision with obstacle segment. */ - line.point = Vector2(0.0F, 0.0F); - line.direction = -obstacle1->direction_; - orcaLines_.push_back(line); - continue; - } - - /* No collision. Compute legs. When obliquely viewed, both legs can come - * from a single vertex. Legs extend cut-off line when nonconvex vertex. */ - Vector2 leftLegDirection; - Vector2 rightLegDirection; - - if (s < 0.0F && distSqLine <= radiusSq) { - /* Obstacle2D viewed obliquely so that left vertex defines velocity - * obstacle. */ - if (!obstacle1->isConvex_) { - /* Ignore obstacle. */ - continue; - } - - obstacle2 = obstacle1; - - const float leg1 = std::sqrt(distSq1 - radiusSq); - leftLegDirection = - Vector2( - relativePosition1.x() * leg1 - relativePosition1.y() * radius_, - relativePosition1.x() * radius_ + relativePosition1.y() * leg1) / - distSq1; - rightLegDirection = - Vector2( - relativePosition1.x() * leg1 + relativePosition1.y() * radius_, - -relativePosition1.x() * radius_ + relativePosition1.y() * leg1) / - distSq1; - } else if (s > 1.0F && distSqLine <= radiusSq) { - /* Obstacle2D viewed obliquely so that right vertex defines velocity - * obstacle. */ - if (!obstacle2->isConvex_) { - /* Ignore obstacle. */ - continue; - } - - obstacle1 = obstacle2; - - const float leg2 = std::sqrt(distSq2 - radiusSq); - leftLegDirection = - Vector2( - relativePosition2.x() * leg2 - relativePosition2.y() * radius_, - relativePosition2.x() * radius_ + relativePosition2.y() * leg2) / - distSq2; - rightLegDirection = - Vector2( - relativePosition2.x() * leg2 + relativePosition2.y() * radius_, - -relativePosition2.x() * radius_ + relativePosition2.y() * leg2) / - distSq2; - } else { - /* Usual situation. */ - if (obstacle1->isConvex_) { - const float leg1 = std::sqrt(distSq1 - radiusSq); - leftLegDirection = Vector2(relativePosition1.x() * leg1 - - relativePosition1.y() * radius_, - relativePosition1.x() * radius_ + - relativePosition1.y() * leg1) / - distSq1; - } else { - /* Left vertex non-convex; left leg extends cut-off line. */ - leftLegDirection = -obstacle1->direction_; - } - - if (obstacle2->isConvex_) { - const float leg2 = std::sqrt(distSq2 - radiusSq); - rightLegDirection = Vector2(relativePosition2.x() * leg2 + - relativePosition2.y() * radius_, - -relativePosition2.x() * radius_ + - relativePosition2.y() * leg2) / - distSq2; - } else { - /* Right vertex non-convex; right leg extends cut-off line. */ - rightLegDirection = obstacle1->direction_; - } - } - - /* Legs can never point into neighboring edge when convex vertex, take - * cutoff-line of neighboring edge instead. If velocity projected on - * "foreign" leg, no constraint is added. */ - const Obstacle2D *const leftNeighbor = obstacle1->previous_; - - bool isLeftLegForeign = false; - bool isRightLegForeign = false; - - if (obstacle1->isConvex_ && - det(leftLegDirection, -leftNeighbor->direction_) >= 0.0F) { - /* Left leg points into obstacle. */ - leftLegDirection = -leftNeighbor->direction_; - isLeftLegForeign = true; - } - - if (obstacle2->isConvex_ && - det(rightLegDirection, obstacle2->direction_) <= 0.0F) { - /* Right leg points into obstacle. */ - rightLegDirection = obstacle2->direction_; - isRightLegForeign = true; - } - - /* Compute cut-off centers. */ - const Vector2 leftCutoff = - invTimeHorizonObst * (obstacle1->point_ - position_); - const Vector2 rightCutoff = - invTimeHorizonObst * (obstacle2->point_ - position_); - const Vector2 cutoffVector = rightCutoff - leftCutoff; - - /* Project current velocity on velocity obstacle. */ - - /* Check if current velocity is projected on cutoff circles. */ - const float t = - obstacle1 == obstacle2 - ? 0.5F - : (velocity_ - leftCutoff) * cutoffVector / absSq(cutoffVector); - const float tLeft = (velocity_ - leftCutoff) * leftLegDirection; - const float tRight = (velocity_ - rightCutoff) * rightLegDirection; - - if ((t < 0.0F && tLeft < 0.0F) || - (obstacle1 == obstacle2 && tLeft < 0.0F && tRight < 0.0F)) { - /* Project on left cut-off circle. */ - const Vector2 unitW = normalize(velocity_ - leftCutoff); - - line.direction = Vector2(unitW.y(), -unitW.x()); - line.point = leftCutoff + radius_ * invTimeHorizonObst * unitW; - orcaLines_.push_back(line); - continue; - } - - if (t > 1.0F && tRight < 0.0F) { - /* Project on right cut-off circle. */ - const Vector2 unitW = normalize(velocity_ - rightCutoff); - - line.direction = Vector2(unitW.y(), -unitW.x()); - line.point = rightCutoff + radius_ * invTimeHorizonObst * unitW; - orcaLines_.push_back(line); - continue; - } - - /* Project on left leg, right leg, or cut-off line, whichever is closest to - * velocity. */ - const float distSqCutoff = - (t < 0.0F || t > 1.0F || obstacle1 == obstacle2) - ? std::numeric_limits<float>::infinity() - : absSq(velocity_ - (leftCutoff + t * cutoffVector)); - const float distSqLeft = - tLeft < 0.0F - ? std::numeric_limits<float>::infinity() - : absSq(velocity_ - (leftCutoff + tLeft * leftLegDirection)); - const float distSqRight = - tRight < 0.0F - ? std::numeric_limits<float>::infinity() - : absSq(velocity_ - (rightCutoff + tRight * rightLegDirection)); - - if (distSqCutoff <= distSqLeft && distSqCutoff <= distSqRight) { - /* Project on cut-off line. */ - line.direction = -obstacle1->direction_; - line.point = - leftCutoff + radius_ * invTimeHorizonObst * - Vector2(-line.direction.y(), line.direction.x()); - orcaLines_.push_back(line); - continue; - } - - if (distSqLeft <= distSqRight) { - /* Project on left leg. */ - if (isLeftLegForeign) { - continue; - } - - line.direction = leftLegDirection; - line.point = - leftCutoff + radius_ * invTimeHorizonObst * - Vector2(-line.direction.y(), line.direction.x()); - orcaLines_.push_back(line); - continue; - } - - /* Project on right leg. */ - if (isRightLegForeign) { - continue; - } - - line.direction = -rightLegDirection; - line.point = - rightCutoff + radius_ * invTimeHorizonObst * - Vector2(-line.direction.y(), line.direction.x()); - orcaLines_.push_back(line); - } - - const std::size_t numObstLines = orcaLines_.size(); - - const float invTimeHorizon = 1.0F / timeHorizon_; - - /* Create agent ORCA lines. */ - for (std::size_t i = 0U; i < agentNeighbors_.size(); ++i) { - const Agent2D *const other = agentNeighbors_[i].second; - - const Vector2 relativePosition = other->position_ - position_; - const Vector2 relativeVelocity = velocity_ - other->velocity_; - const float distSq = absSq(relativePosition); - const float combinedRadius = radius_ + other->radius_; - const float combinedRadiusSq = combinedRadius * combinedRadius; - - Line line; - Vector2 u; - - if (distSq > combinedRadiusSq) { - /* No collision. */ - const Vector2 w = relativeVelocity - invTimeHorizon * relativePosition; - /* Vector from cutoff center to relative velocity. */ - const float wLengthSq = absSq(w); - - const float dotProduct = w * relativePosition; - - if (dotProduct < 0.0F && - dotProduct * dotProduct > combinedRadiusSq * wLengthSq) { - /* Project on cut-off circle. */ - const float wLength = std::sqrt(wLengthSq); - const Vector2 unitW = w / wLength; - - line.direction = Vector2(unitW.y(), -unitW.x()); - u = (combinedRadius * invTimeHorizon - wLength) * unitW; - } else { - /* Project on legs. */ - const float leg = std::sqrt(distSq - combinedRadiusSq); - - if (det(relativePosition, w) > 0.0F) { - /* Project on left leg. */ - line.direction = Vector2(relativePosition.x() * leg - - relativePosition.y() * combinedRadius, - relativePosition.x() * combinedRadius + - relativePosition.y() * leg) / - distSq; - } else { - /* Project on right leg. */ - line.direction = -Vector2(relativePosition.x() * leg + - relativePosition.y() * combinedRadius, - -relativePosition.x() * combinedRadius + - relativePosition.y() * leg) / - distSq; - } - - u = (relativeVelocity * line.direction) * line.direction - - relativeVelocity; - } - } else { - /* Collision. Project on cut-off circle of time timeStep. */ - const float invTimeStep = 1.0F / timeStep; - - /* Vector from cutoff center to relative velocity. */ - const Vector2 w = relativeVelocity - invTimeStep * relativePosition; - - const float wLength = abs(w); - const Vector2 unitW = w / wLength; - - line.direction = Vector2(unitW.y(), -unitW.x()); - u = (combinedRadius * invTimeStep - wLength) * unitW; - } - - line.point = velocity_ + 0.5F * u; - orcaLines_.push_back(line); - } - - const std::size_t lineFail = - linearProgram2(orcaLines_, maxSpeed_, prefVelocity_, false, newVelocity_); - - if (lineFail < orcaLines_.size()) { - linearProgram3(orcaLines_, numObstLines, lineFail, maxSpeed_, newVelocity_); - } -} - -void Agent2D::insertAgentNeighbor(const Agent2D *agent, float &rangeSq) { - // no point processing same agent - if (this == agent) { - return; - } - // ignore other agent if layers/mask bitmasks have no matching bit - if ((avoidance_mask_ & agent->avoidance_layers_) == 0) { - return; - } - // ignore other agent if this agent is below or above - if ((elevation_ > agent->elevation_ + agent->height_) || (elevation_ + height_ < agent->elevation_)) { - return; - } - - if (avoidance_priority_ > agent->avoidance_priority_) { - return; - } - const float distSq = absSq(position_ - agent->position_); - - if (distSq < rangeSq) { - if (agentNeighbors_.size() < maxNeighbors_) { - agentNeighbors_.push_back(std::make_pair(distSq, agent)); - } - - std::size_t i = agentNeighbors_.size() - 1U; - - while (i != 0U && distSq < agentNeighbors_[i - 1U].first) { - agentNeighbors_[i] = agentNeighbors_[i - 1U]; - --i; - } - - agentNeighbors_[i] = std::make_pair(distSq, agent); - - if (agentNeighbors_.size() == maxNeighbors_) { - rangeSq = agentNeighbors_.back().first; - } - } -} - -void Agent2D::insertObstacleNeighbor(const Obstacle2D *obstacle, float rangeSq) { - const Obstacle2D *const nextObstacle = obstacle->next_; - - float distSq = 0.0F; - const float r = ((position_ - obstacle->point_) * - (nextObstacle->point_ - obstacle->point_)) / - absSq(nextObstacle->point_ - obstacle->point_); - - if (r < 0.0F) { - distSq = absSq(position_ - obstacle->point_); - } else if (r > 1.0F) { - distSq = absSq(position_ - nextObstacle->point_); - } else { - distSq = absSq(position_ - (obstacle->point_ + - r * (nextObstacle->point_ - obstacle->point_))); - } - - if (distSq < rangeSq) { - obstacleNeighbors_.push_back(std::make_pair(distSq, obstacle)); - - std::size_t i = obstacleNeighbors_.size() - 1U; - - while (i != 0U && distSq < obstacleNeighbors_[i - 1U].first) { - obstacleNeighbors_[i] = obstacleNeighbors_[i - 1U]; - --i; - } - - obstacleNeighbors_[i] = std::make_pair(distSq, obstacle); - } -} - -void Agent2D::update(float timeStep) { - velocity_ = newVelocity_; - position_ += velocity_ * timeStep; -} -} /* namespace RVO2D */ diff --git a/thirdparty/rvo2/rvo2_2d/Agent2d.cpp b/thirdparty/rvo2/rvo2_2d/Agent2d.cpp new file mode 100644 index 0000000000..3ff95a4922 --- /dev/null +++ b/thirdparty/rvo2/rvo2_2d/Agent2d.cpp @@ -0,0 +1,594 @@ +/* + * Agent2d.cpp + * RVO2 Library + * + * Copyright 2008 University of North Carolina at Chapel Hill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Please send all bug reports to <geom@cs.unc.edu>. + * + * The authors may be contacted via: + * + * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha + * Dept. of Computer Science + * 201 S. Columbia St. + * Frederick P. Brooks, Jr. Computer Science Bldg. + * Chapel Hill, N.C. 27599-3175 + * United States of America + * + * <http://gamma.cs.unc.edu/RVO2/> + */ + +#include "Agent2d.h" + +#include "KdTree2d.h" +#include "Obstacle2d.h" + +namespace RVO2D { + Agent2D::Agent2D() : maxNeighbors_(0), maxSpeed_(0.0f), neighborDist_(0.0f), radius_(0.0f), timeHorizon_(0.0f), timeHorizonObst_(0.0f), id_(0) { } + + void Agent2D::computeNeighbors(RVOSimulator2D *sim_) + { + obstacleNeighbors_.clear(); + float rangeSq = sqr(timeHorizonObst_ * maxSpeed_ + radius_); + sim_->kdTree_->computeObstacleNeighbors(this, rangeSq); + + agentNeighbors_.clear(); + + if (maxNeighbors_ > 0) { + rangeSq = sqr(neighborDist_); + sim_->kdTree_->computeAgentNeighbors(this, rangeSq); + } + } + + /* Search for the best new velocity. */ + void Agent2D::computeNewVelocity(RVOSimulator2D *sim_) + { + orcaLines_.clear(); + + const float invTimeHorizonObst = 1.0f / timeHorizonObst_; + + /* Create obstacle ORCA lines. */ + for (size_t i = 0; i < obstacleNeighbors_.size(); ++i) { + + const Obstacle2D *obstacle1 = obstacleNeighbors_[i].second; + const Obstacle2D *obstacle2 = obstacle1->nextObstacle_; + + const Vector2 relativePosition1 = obstacle1->point_ - position_; + const Vector2 relativePosition2 = obstacle2->point_ - position_; + + /* + * Check if velocity obstacle of obstacle is already taken care of by + * previously constructed obstacle ORCA lines. + */ + bool alreadyCovered = false; + + for (size_t j = 0; j < orcaLines_.size(); ++j) { + if (det(invTimeHorizonObst * relativePosition1 - orcaLines_[j].point, orcaLines_[j].direction) - invTimeHorizonObst * radius_ >= -RVO_EPSILON && det(invTimeHorizonObst * relativePosition2 - orcaLines_[j].point, orcaLines_[j].direction) - invTimeHorizonObst * radius_ >= -RVO_EPSILON) { + alreadyCovered = true; + break; + } + } + + if (alreadyCovered) { + continue; + } + + /* Not yet covered. Check for collisions. */ + + const float distSq1 = absSq(relativePosition1); + const float distSq2 = absSq(relativePosition2); + + const float radiusSq = sqr(radius_); + + const Vector2 obstacleVector = obstacle2->point_ - obstacle1->point_; + const float s = (-relativePosition1 * obstacleVector) / absSq(obstacleVector); + const float distSqLine = absSq(-relativePosition1 - s * obstacleVector); + + Line line; + + if (s < 0.0f && distSq1 <= radiusSq) { + /* Collision with left vertex. Ignore if non-convex. */ + if (obstacle1->isConvex_) { + line.point = Vector2(0.0f, 0.0f); + line.direction = normalize(Vector2(-relativePosition1.y(), relativePosition1.x())); + orcaLines_.push_back(line); + } + + continue; + } + else if (s > 1.0f && distSq2 <= radiusSq) { + /* Collision with right vertex. Ignore if non-convex + * or if it will be taken care of by neighoring obstace */ + if (obstacle2->isConvex_ && det(relativePosition2, obstacle2->unitDir_) >= 0.0f) { + line.point = Vector2(0.0f, 0.0f); + line.direction = normalize(Vector2(-relativePosition2.y(), relativePosition2.x())); + orcaLines_.push_back(line); + } + + continue; + } + else if (s >= 0.0f && s < 1.0f && distSqLine <= radiusSq) { + /* Collision with obstacle segment. */ + line.point = Vector2(0.0f, 0.0f); + line.direction = -obstacle1->unitDir_; + orcaLines_.push_back(line); + continue; + } + + /* + * No collision. + * Compute legs. When obliquely viewed, both legs can come from a single + * vertex. Legs extend cut-off line when nonconvex vertex. + */ + + Vector2 leftLegDirection, rightLegDirection; + + if (s < 0.0f && distSqLine <= radiusSq) { + /* + * Obstacle viewed obliquely so that left vertex + * defines velocity obstacle. + */ + if (!obstacle1->isConvex_) { + /* Ignore obstacle. */ + continue; + } + + obstacle2 = obstacle1; + + const float leg1 = std::sqrt(distSq1 - radiusSq); + leftLegDirection = Vector2(relativePosition1.x() * leg1 - relativePosition1.y() * radius_, relativePosition1.x() * radius_ + relativePosition1.y() * leg1) / distSq1; + rightLegDirection = Vector2(relativePosition1.x() * leg1 + relativePosition1.y() * radius_, -relativePosition1.x() * radius_ + relativePosition1.y() * leg1) / distSq1; + } + else if (s > 1.0f && distSqLine <= radiusSq) { + /* + * Obstacle viewed obliquely so that + * right vertex defines velocity obstacle. + */ + if (!obstacle2->isConvex_) { + /* Ignore obstacle. */ + continue; + } + + obstacle1 = obstacle2; + + const float leg2 = std::sqrt(distSq2 - radiusSq); + leftLegDirection = Vector2(relativePosition2.x() * leg2 - relativePosition2.y() * radius_, relativePosition2.x() * radius_ + relativePosition2.y() * leg2) / distSq2; + rightLegDirection = Vector2(relativePosition2.x() * leg2 + relativePosition2.y() * radius_, -relativePosition2.x() * radius_ + relativePosition2.y() * leg2) / distSq2; + } + else { + /* Usual situation. */ + if (obstacle1->isConvex_) { + const float leg1 = std::sqrt(distSq1 - radiusSq); + leftLegDirection = Vector2(relativePosition1.x() * leg1 - relativePosition1.y() * radius_, relativePosition1.x() * radius_ + relativePosition1.y() * leg1) / distSq1; + } + else { + /* Left vertex non-convex; left leg extends cut-off line. */ + leftLegDirection = -obstacle1->unitDir_; + } + + if (obstacle2->isConvex_) { + const float leg2 = std::sqrt(distSq2 - radiusSq); + rightLegDirection = Vector2(relativePosition2.x() * leg2 + relativePosition2.y() * radius_, -relativePosition2.x() * radius_ + relativePosition2.y() * leg2) / distSq2; + } + else { + /* Right vertex non-convex; right leg extends cut-off line. */ + rightLegDirection = obstacle1->unitDir_; + } + } + + /* + * Legs can never point into neighboring edge when convex vertex, + * take cutoff-line of neighboring edge instead. If velocity projected on + * "foreign" leg, no constraint is added. + */ + + const Obstacle2D *const leftNeighbor = obstacle1->prevObstacle_; + + bool isLeftLegForeign = false; + bool isRightLegForeign = false; + + if (obstacle1->isConvex_ && det(leftLegDirection, -leftNeighbor->unitDir_) >= 0.0f) { + /* Left leg points into obstacle. */ + leftLegDirection = -leftNeighbor->unitDir_; + isLeftLegForeign = true; + } + + if (obstacle2->isConvex_ && det(rightLegDirection, obstacle2->unitDir_) <= 0.0f) { + /* Right leg points into obstacle. */ + rightLegDirection = obstacle2->unitDir_; + isRightLegForeign = true; + } + + /* Compute cut-off centers. */ + const Vector2 leftCutoff = invTimeHorizonObst * (obstacle1->point_ - position_); + const Vector2 rightCutoff = invTimeHorizonObst * (obstacle2->point_ - position_); + const Vector2 cutoffVec = rightCutoff - leftCutoff; + + /* Project current velocity on velocity obstacle. */ + + /* Check if current velocity is projected on cutoff circles. */ + const float t = (obstacle1 == obstacle2 ? 0.5f : ((velocity_ - leftCutoff) * cutoffVec) / absSq(cutoffVec)); + const float tLeft = ((velocity_ - leftCutoff) * leftLegDirection); + const float tRight = ((velocity_ - rightCutoff) * rightLegDirection); + + if ((t < 0.0f && tLeft < 0.0f) || (obstacle1 == obstacle2 && tLeft < 0.0f && tRight < 0.0f)) { + /* Project on left cut-off circle. */ + const Vector2 unitW = normalize(velocity_ - leftCutoff); + + line.direction = Vector2(unitW.y(), -unitW.x()); + line.point = leftCutoff + radius_ * invTimeHorizonObst * unitW; + orcaLines_.push_back(line); + continue; + } + else if (t > 1.0f && tRight < 0.0f) { + /* Project on right cut-off circle. */ + const Vector2 unitW = normalize(velocity_ - rightCutoff); + + line.direction = Vector2(unitW.y(), -unitW.x()); + line.point = rightCutoff + radius_ * invTimeHorizonObst * unitW; + orcaLines_.push_back(line); + continue; + } + + /* + * Project on left leg, right leg, or cut-off line, whichever is closest + * to velocity. + */ + const float distSqCutoff = ((t < 0.0f || t > 1.0f || obstacle1 == obstacle2) ? std::numeric_limits<float>::infinity() : absSq(velocity_ - (leftCutoff + t * cutoffVec))); + const float distSqLeft = ((tLeft < 0.0f) ? std::numeric_limits<float>::infinity() : absSq(velocity_ - (leftCutoff + tLeft * leftLegDirection))); + const float distSqRight = ((tRight < 0.0f) ? std::numeric_limits<float>::infinity() : absSq(velocity_ - (rightCutoff + tRight * rightLegDirection))); + + if (distSqCutoff <= distSqLeft && distSqCutoff <= distSqRight) { + /* Project on cut-off line. */ + line.direction = -obstacle1->unitDir_; + line.point = leftCutoff + radius_ * invTimeHorizonObst * Vector2(-line.direction.y(), line.direction.x()); + orcaLines_.push_back(line); + continue; + } + else if (distSqLeft <= distSqRight) { + /* Project on left leg. */ + if (isLeftLegForeign) { + continue; + } + + line.direction = leftLegDirection; + line.point = leftCutoff + radius_ * invTimeHorizonObst * Vector2(-line.direction.y(), line.direction.x()); + orcaLines_.push_back(line); + continue; + } + else { + /* Project on right leg. */ + if (isRightLegForeign) { + continue; + } + + line.direction = -rightLegDirection; + line.point = rightCutoff + radius_ * invTimeHorizonObst * Vector2(-line.direction.y(), line.direction.x()); + orcaLines_.push_back(line); + continue; + } + } + + const size_t numObstLines = orcaLines_.size(); + + const float invTimeHorizon = 1.0f / timeHorizon_; + + /* Create agent ORCA lines. */ + for (size_t i = 0; i < agentNeighbors_.size(); ++i) { + const Agent2D *const other = agentNeighbors_[i].second; + + //const float timeHorizon_mod = (avoidance_priority_ - other->avoidance_priority_ + 1.0f) * 0.5f; + //const float invTimeHorizon = (1.0f / timeHorizon_) * timeHorizon_mod; + + const Vector2 relativePosition = other->position_ - position_; + const Vector2 relativeVelocity = velocity_ - other->velocity_; + const float distSq = absSq(relativePosition); + const float combinedRadius = radius_ + other->radius_; + const float combinedRadiusSq = sqr(combinedRadius); + + Line line; + Vector2 u; + + if (distSq > combinedRadiusSq) { + /* No collision. */ + const Vector2 w = relativeVelocity - invTimeHorizon * relativePosition; + /* Vector from cutoff center to relative velocity. */ + const float wLengthSq = absSq(w); + + const float dotProduct1 = w * relativePosition; + + if (dotProduct1 < 0.0f && sqr(dotProduct1) > combinedRadiusSq * wLengthSq) { + /* Project on cut-off circle. */ + const float wLength = std::sqrt(wLengthSq); + const Vector2 unitW = w / wLength; + + line.direction = Vector2(unitW.y(), -unitW.x()); + u = (combinedRadius * invTimeHorizon - wLength) * unitW; + } + else { + /* Project on legs. */ + const float leg = std::sqrt(distSq - combinedRadiusSq); + + if (det(relativePosition, w) > 0.0f) { + /* Project on left leg. */ + line.direction = Vector2(relativePosition.x() * leg - relativePosition.y() * combinedRadius, relativePosition.x() * combinedRadius + relativePosition.y() * leg) / distSq; + } + else { + /* Project on right leg. */ + line.direction = -Vector2(relativePosition.x() * leg + relativePosition.y() * combinedRadius, -relativePosition.x() * combinedRadius + relativePosition.y() * leg) / distSq; + } + + const float dotProduct2 = relativeVelocity * line.direction; + + u = dotProduct2 * line.direction - relativeVelocity; + } + } + else { + /* Collision. Project on cut-off circle of time timeStep. */ + const float invTimeStep = 1.0f / sim_->timeStep_; + + /* Vector from cutoff center to relative velocity. */ + const Vector2 w = relativeVelocity - invTimeStep * relativePosition; + + const float wLength = abs(w); + const Vector2 unitW = w / wLength; + + line.direction = Vector2(unitW.y(), -unitW.x()); + u = (combinedRadius * invTimeStep - wLength) * unitW; + } + + line.point = velocity_ + 0.5f * u; + orcaLines_.push_back(line); + } + + size_t lineFail = linearProgram2(orcaLines_, maxSpeed_, prefVelocity_, false, newVelocity_); + + if (lineFail < orcaLines_.size()) { + linearProgram3(orcaLines_, numObstLines, lineFail, maxSpeed_, newVelocity_); + } + } + + void Agent2D::insertAgentNeighbor(const Agent2D *agent, float &rangeSq) + { + // no point processing same agent + if (this == agent) { + return; + } + // ignore other agent if layers/mask bitmasks have no matching bit + if ((avoidance_mask_ & agent->avoidance_layers_) == 0) { + return; + } + // ignore other agent if this agent is below or above + if ((elevation_ > agent->elevation_ + agent->height_) || (elevation_ + height_ < agent->elevation_)) { + return; + } + + if (avoidance_priority_ > agent->avoidance_priority_) { + return; + } + + const float distSq = absSq(position_ - agent->position_); + + if (distSq < rangeSq) { + if (agentNeighbors_.size() < maxNeighbors_) { + agentNeighbors_.push_back(std::make_pair(distSq, agent)); + } + + size_t i = agentNeighbors_.size() - 1; + + while (i != 0 && distSq < agentNeighbors_[i - 1].first) { + agentNeighbors_[i] = agentNeighbors_[i - 1]; + --i; + } + + agentNeighbors_[i] = std::make_pair(distSq, agent); + + if (agentNeighbors_.size() == maxNeighbors_) { + rangeSq = agentNeighbors_.back().first; + } + } + } + + void Agent2D::insertObstacleNeighbor(const Obstacle2D *obstacle, float rangeSq) + { + const Obstacle2D *const nextObstacle = obstacle->nextObstacle_; + + // ignore obstacle if no matching layer/mask + if ((avoidance_mask_ & nextObstacle->avoidance_layers_) == 0) { + return; + } + // ignore obstacle if below or above + if ((elevation_ > obstacle->elevation_ + obstacle->height_) || (elevation_ + height_ < obstacle->elevation_)) { + return; + } + + const float distSq = distSqPointLineSegment(obstacle->point_, nextObstacle->point_, position_); + + if (distSq < rangeSq) { + obstacleNeighbors_.push_back(std::make_pair(distSq, obstacle)); + + size_t i = obstacleNeighbors_.size() - 1; + + while (i != 0 && distSq < obstacleNeighbors_[i - 1].first) { + obstacleNeighbors_[i] = obstacleNeighbors_[i - 1]; + --i; + } + + obstacleNeighbors_[i] = std::make_pair(distSq, obstacle); + } + //} + } + + void Agent2D::update(RVOSimulator2D *sim_) + { + velocity_ = newVelocity_; + position_ += velocity_ * sim_->timeStep_; + } + + bool linearProgram1(const std::vector<Line> &lines, size_t lineNo, float radius, const Vector2 &optVelocity, bool directionOpt, Vector2 &result) + { + const float dotProduct = lines[lineNo].point * lines[lineNo].direction; + const float discriminant = sqr(dotProduct) + sqr(radius) - absSq(lines[lineNo].point); + + if (discriminant < 0.0f) { + /* Max speed circle fully invalidates line lineNo. */ + return false; + } + + const float sqrtDiscriminant = std::sqrt(discriminant); + float tLeft = -dotProduct - sqrtDiscriminant; + float tRight = -dotProduct + sqrtDiscriminant; + + for (size_t i = 0; i < lineNo; ++i) { + const float denominator = det(lines[lineNo].direction, lines[i].direction); + const float numerator = det(lines[i].direction, lines[lineNo].point - lines[i].point); + + if (std::fabs(denominator) <= RVO_EPSILON) { + /* Lines lineNo and i are (almost) parallel. */ + if (numerator < 0.0f) { + return false; + } + else { + continue; + } + } + + const float t = numerator / denominator; + + if (denominator >= 0.0f) { + /* Line i bounds line lineNo on the right. */ + tRight = std::min(tRight, t); + } + else { + /* Line i bounds line lineNo on the left. */ + tLeft = std::max(tLeft, t); + } + + if (tLeft > tRight) { + return false; + } + } + + if (directionOpt) { + /* Optimize direction. */ + if (optVelocity * lines[lineNo].direction > 0.0f) { + /* Take right extreme. */ + result = lines[lineNo].point + tRight * lines[lineNo].direction; + } + else { + /* Take left extreme. */ + result = lines[lineNo].point + tLeft * lines[lineNo].direction; + } + } + else { + /* Optimize closest point. */ + const float t = lines[lineNo].direction * (optVelocity - lines[lineNo].point); + + if (t < tLeft) { + result = lines[lineNo].point + tLeft * lines[lineNo].direction; + } + else if (t > tRight) { + result = lines[lineNo].point + tRight * lines[lineNo].direction; + } + else { + result = lines[lineNo].point + t * lines[lineNo].direction; + } + } + + return true; + } + + size_t linearProgram2(const std::vector<Line> &lines, float radius, const Vector2 &optVelocity, bool directionOpt, Vector2 &result) + { + if (directionOpt) { + /* + * Optimize direction. Note that the optimization velocity is of unit + * length in this case. + */ + result = optVelocity * radius; + } + else if (absSq(optVelocity) > sqr(radius)) { + /* Optimize closest point and outside circle. */ + result = normalize(optVelocity) * radius; + } + else { + /* Optimize closest point and inside circle. */ + result = optVelocity; + } + + for (size_t i = 0; i < lines.size(); ++i) { + if (det(lines[i].direction, lines[i].point - result) > 0.0f) { + /* Result does not satisfy constraint i. Compute new optimal result. */ + const Vector2 tempResult = result; + + if (!linearProgram1(lines, i, radius, optVelocity, directionOpt, result)) { + result = tempResult; + return i; + } + } + } + + return lines.size(); + } + + void linearProgram3(const std::vector<Line> &lines, size_t numObstLines, size_t beginLine, float radius, Vector2 &result) + { + float distance = 0.0f; + + for (size_t i = beginLine; i < lines.size(); ++i) { + if (det(lines[i].direction, lines[i].point - result) > distance) { + /* Result does not satisfy constraint of line i. */ + std::vector<Line> projLines(lines.begin(), lines.begin() + static_cast<ptrdiff_t>(numObstLines)); + + for (size_t j = numObstLines; j < i; ++j) { + Line line; + + float determinant = det(lines[i].direction, lines[j].direction); + + if (std::fabs(determinant) <= RVO_EPSILON) { + /* Line i and line j are parallel. */ + if (lines[i].direction * lines[j].direction > 0.0f) { + /* Line i and line j point in the same direction. */ + continue; + } + else { + /* Line i and line j point in opposite direction. */ + line.point = 0.5f * (lines[i].point + lines[j].point); + } + } + else { + line.point = lines[i].point + (det(lines[j].direction, lines[i].point - lines[j].point) / determinant) * lines[i].direction; + } + + line.direction = normalize(lines[j].direction - lines[i].direction); + projLines.push_back(line); + } + + const Vector2 tempResult = result; + + if (linearProgram2(projLines, radius, Vector2(-lines[i].direction.y(), lines[i].direction.x()), true, result) < projLines.size()) { + /* This should in principle not happen. The result is by definition + * already in the feasible region of this linear program. If it fails, + * it is due to small floating point error, and the current result is + * kept. + */ + result = tempResult; + } + + distance = det(lines[i].direction, lines[i].point - result); + } + } + } +} diff --git a/thirdparty/rvo2/rvo2_2d/Agent2d.h b/thirdparty/rvo2/rvo2_2d/Agent2d.h index f5b9ed8ebc..c666c2de7b 100644 --- a/thirdparty/rvo2/rvo2_2d/Agent2d.h +++ b/thirdparty/rvo2/rvo2_2d/Agent2d.h @@ -2,14 +2,13 @@ * Agent2d.h * RVO2 Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,110 +27,134 @@ * Chapel Hill, N.C. 27599-3175 * United States of America * - * <https://gamma.cs.unc.edu/RVO2/> + * <http://gamma.cs.unc.edu/RVO2/> */ #ifndef RVO2D_AGENT_H_ #define RVO2D_AGENT_H_ /** - * @file Agent2d.h - * @brief Declares the Agent2D class. + * \file Agent2d.h + * \brief Contains the Agent class. */ -#include <cstddef> -#include <cstdint> -#include <utility> -#include <vector> - -#include "Line.h" -#include "Vector2.h" +#include "Definitions.h" +#include "RVOSimulator2d.h" namespace RVO2D { -class KdTree2D; -class Obstacle2D; - -/** - * @brief Defines an agent in the simulation. - */ -class Agent2D { - public: - /** - * @brief Constructs an agent instance. - */ - Agent2D(); - - /** - * @brief Destroys this agent instance. - */ - ~Agent2D(); - - /** - * @brief Computes the neighbors of this agent. - * @param[in] kdTree A pointer to the k-D trees for agents and static - * obstacles in the simulation. - */ - void computeNeighbors(const KdTree2D *kdTree); - - /** - * @brief Computes the new velocity of this agent. - * @param[in] timeStep The time step of the simulation. - */ - void computeNewVelocity(float timeStep); - - /** - * @brief Inserts an agent neighbor into the set of neighbors of this - * agent. - * @param[in] agent A pointer to the agent to be inserted. - * @param[in, out] rangeSq The squared range around this agent. - */ - void insertAgentNeighbor(const Agent2D *agent, - float &rangeSq); /* NOLINT(runtime/references) */ - - /** - * @brief Inserts a static obstacle neighbor into the set of - * neighbors of this agent. - * @param[in] obstacle The number of the static obstacle to be inserted. - * @param[in, out] rangeSq The squared range around this agent. - */ - void insertObstacleNeighbor(const Obstacle2D *obstacle, float rangeSq); - - /** - * @brief Updates the two-dimensional position and two-dimensional - * velocity of this agent. - * @param[in] timeStep The time step of the simulation. - */ - void update(float timeStep); - - /* Not implemented. */ - Agent2D(const Agent2D &other); - - /* Not implemented. */ - Agent2D &operator=(const Agent2D &other); - - std::vector<std::pair<float, const Agent2D *> > agentNeighbors_; - std::vector<std::pair<float, const Obstacle2D *> > obstacleNeighbors_; - std::vector<Line> orcaLines_; - Vector2 newVelocity_; - Vector2 position_; - Vector2 prefVelocity_; - Vector2 velocity_; - std::size_t id_; - std::size_t maxNeighbors_; - float maxSpeed_; - float neighborDist_; - float radius_; - float timeHorizon_; - float timeHorizonObst_; - float height_ = 0.0; - float elevation_ = 0.0; - uint32_t avoidance_layers_ = 1; - uint32_t avoidance_mask_ = 1; - float avoidance_priority_ = 1.0; - - friend class KdTree2D; - friend class RVOSimulator2D; -}; -} /* namespace RVO */ + /** + * \brief Defines an agent in the simulation. + */ + class Agent2D { + public: + /** + * \brief Constructs an agent instance. + * \param sim The simulator instance. + */ + explicit Agent2D(); + + /** + * \brief Computes the neighbors of this agent. + */ + void computeNeighbors(RVOSimulator2D *sim_); + + /** + * \brief Computes the new velocity of this agent. + */ + void computeNewVelocity(RVOSimulator2D *sim_); + + /** + * \brief Inserts an agent neighbor into the set of neighbors of + * this agent. + * \param agent A pointer to the agent to be inserted. + * \param rangeSq The squared range around this agent. + */ + void insertAgentNeighbor(const Agent2D *agent, float &rangeSq); + + /** + * \brief Inserts a static obstacle neighbor into the set of neighbors + * of this agent. + * \param obstacle The number of the static obstacle to be + * inserted. + * \param rangeSq The squared range around this agent. + */ + void insertObstacleNeighbor(const Obstacle2D *obstacle, float rangeSq); + + /** + * \brief Updates the two-dimensional position and two-dimensional + * velocity of this agent. + */ + void update(RVOSimulator2D *sim_); + + std::vector<std::pair<float, const Agent2D *> > agentNeighbors_; + size_t maxNeighbors_; + float maxSpeed_; + float neighborDist_; + Vector2 newVelocity_; + std::vector<std::pair<float, const Obstacle2D *> > obstacleNeighbors_; + std::vector<Line> orcaLines_; + Vector2 position_; + Vector2 prefVelocity_; + float radius_; + float timeHorizon_; + float timeHorizonObst_; + Vector2 velocity_; + float height_ = 0.0; + float elevation_ = 0.0; + uint32_t avoidance_layers_ = 1; + uint32_t avoidance_mask_ = 1; + float avoidance_priority_ = 1.0; + + size_t id_; + + friend class KdTree2D; + friend class RVOSimulator2D; + }; + + /** + * \relates Agent + * \brief Solves a one-dimensional linear program on a specified line + * subject to linear constraints defined by lines and a circular + * constraint. + * \param lines Lines defining the linear constraints. + * \param lineNo The specified line constraint. + * \param radius The radius of the circular constraint. + * \param optVelocity The optimization velocity. + * \param directionOpt True if the direction should be optimized. + * \param result A reference to the result of the linear program. + * \return True if successful. + */ + bool linearProgram1(const std::vector<Line> &lines, size_t lineNo, + float radius, const Vector2 &optVelocity, + bool directionOpt, Vector2 &result); + + /** + * \relates Agent + * \brief Solves a two-dimensional linear program subject to linear + * constraints defined by lines and a circular constraint. + * \param lines Lines defining the linear constraints. + * \param radius The radius of the circular constraint. + * \param optVelocity The optimization velocity. + * \param directionOpt True if the direction should be optimized. + * \param result A reference to the result of the linear program. + * \return The number of the line it fails on, and the number of lines if successful. + */ + size_t linearProgram2(const std::vector<Line> &lines, float radius, + const Vector2 &optVelocity, bool directionOpt, + Vector2 &result); + + /** + * \relates Agent + * \brief Solves a two-dimensional linear program subject to linear + * constraints defined by lines and a circular constraint. + * \param lines Lines defining the linear constraints. + * \param numObstLines Count of obstacle lines. + * \param beginLine The line on which the 2-d linear program failed. + * \param radius The radius of the circular constraint. + * \param result A reference to the result of the linear program. + */ + void linearProgram3(const std::vector<Line> &lines, size_t numObstLines, size_t beginLine, + float radius, Vector2 &result); +} #endif /* RVO2D_AGENT_H_ */ diff --git a/thirdparty/rvo2/rvo2_2d/Definitions.h b/thirdparty/rvo2/rvo2_2d/Definitions.h new file mode 100644 index 0000000000..a5553d8378 --- /dev/null +++ b/thirdparty/rvo2/rvo2_2d/Definitions.h @@ -0,0 +1,110 @@ +/* + * Definitions.h + * RVO2 Library + * + * Copyright 2008 University of North Carolina at Chapel Hill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Please send all bug reports to <geom@cs.unc.edu>. + * + * The authors may be contacted via: + * + * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha + * Dept. of Computer Science + * 201 S. Columbia St. + * Frederick P. Brooks, Jr. Computer Science Bldg. + * Chapel Hill, N.C. 27599-3175 + * United States of America + * + * <http://gamma.cs.unc.edu/RVO2/> + */ + +#ifndef RVO2D_DEFINITIONS_H_ +#define RVO2D_DEFINITIONS_H_ + +/** + * \file Definitions.h + * \brief Contains functions and constants used in multiple classes. + */ + +#include <algorithm> +#include <cmath> +#include <cstddef> +#include <cstdint> +#include <limits> +#include <vector> + +#include "Vector2.h" + +/** + * \brief A sufficiently small positive number. + */ +const float RVO_EPSILON = 0.00001f; + +namespace RVO2D { + class Agent2D; + class Obstacle2D; + class RVOSimulator2D; + + /** + * \brief Computes the squared distance from a line segment with the + * specified endpoints to a specified point. + * \param a The first endpoint of the line segment. + * \param b The second endpoint of the line segment. + * \param c The point to which the squared distance is to + * be calculated. + * \return The squared distance from the line segment to the point. + */ + inline float distSqPointLineSegment(const Vector2 &a, const Vector2 &b, + const Vector2 &c) + { + const float r = ((c - a) * (b - a)) / absSq(b - a); + + if (r < 0.0f) { + return absSq(c - a); + } + else if (r > 1.0f) { + return absSq(c - b); + } + else { + return absSq(c - (a + r * (b - a))); + } + } + + /** + * \brief Computes the signed distance from a line connecting the + * specified points to a specified point. + * \param a The first point on the line. + * \param b The second point on the line. + * \param c The point to which the signed distance is to + * be calculated. + * \return Positive when the point c lies to the left of the line ab. + */ + inline float leftOf(const Vector2 &a, const Vector2 &b, const Vector2 &c) + { + return det(a - c, b - a); + } + + /** + * \brief Computes the square of a float. + * \param a The float to be squared. + * \return The square of the float. + */ + inline float sqr(float a) + { + return a * a; + } +} + +#endif /* RVO2D_DEFINITIONS_H_ */ diff --git a/thirdparty/rvo2/rvo2_2d/KdTree2d.cc b/thirdparty/rvo2/rvo2_2d/KdTree2d.cc deleted file mode 100644 index 6259a5d661..0000000000 --- a/thirdparty/rvo2/rvo2_2d/KdTree2d.cc +++ /dev/null @@ -1,517 +0,0 @@ -/* - * KdTree2d.cpp - * RVO2 Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -/** - * @file KdTree2d.cpp - * @brief Defines the KdTree2D class. - */ - -#include "KdTree2d.h" - -#include <algorithm> -#include <utility> - -#include "Agent2d.h" -#include "Obstacle2d.h" -#include "RVOSimulator2d.h" -#include "Vector2.h" - -namespace RVO2D { -namespace { -/** - * @relates KdTree2D - * @brief The maximum k-D tree node leaf size. - */ -const std::size_t RVO_MAX_LEAF_SIZE = 10U; -} /* namespace */ - -/** - * @brief Defines an agent k-D tree node. - */ -class KdTree2D::AgentTreeNode { - public: - /** - * @brief Constructs an agent k-D tree node instance. - */ - AgentTreeNode(); - - /** - * @brief The beginning node number. - */ - std::size_t begin; - - /** - * @brief The ending node number. - */ - std::size_t end; - - /** - * @brief The left node number. - */ - std::size_t left; - - /** - * @brief The right node number. - */ - std::size_t right; - - /** - * @brief The maximum x-coordinate. - */ - float maxX; - - /** - * @brief The maximum y-coordinate. - */ - float maxY; - - /** - * @brief The minimum x-coordinate. - */ - float minX; - - /** - * @brief The minimum y-coordinate. - */ - float minY; -}; - -KdTree2D::AgentTreeNode::AgentTreeNode() - : begin(0U), - end(0U), - left(0U), - right(0U), - maxX(0.0F), - maxY(0.0F), - minX(0.0F), - minY(0.0F) {} - -/** - * @brief Defines an obstacle k-D tree node. - */ -class KdTree2D::ObstacleTreeNode { - public: - /** - * @brief Constructs an obstacle k-D tree node instance. - */ - ObstacleTreeNode(); - - /** - * @brief Destroys this obstacle k-D tree node instance. - */ - ~ObstacleTreeNode(); - - /** - * @brief The obstacle number. - */ - const Obstacle2D *obstacle; - - /** - * @brief The left obstacle tree node. - */ - ObstacleTreeNode *left; - - /** - * @brief The right obstacle tree node. - */ - ObstacleTreeNode *right; - - private: - /* Not implemented. */ - ObstacleTreeNode(const ObstacleTreeNode &other); - - /* Not implemented. */ - ObstacleTreeNode &operator=(const ObstacleTreeNode &other); -}; - -KdTree2D::ObstacleTreeNode::ObstacleTreeNode() - : obstacle(NULL), left(NULL), right(NULL) {} - -KdTree2D::ObstacleTreeNode::~ObstacleTreeNode() {} - -KdTree2D::KdTree2D(RVOSimulator2D *simulator) - : obstacleTree_(NULL), simulator_(simulator) {} - -KdTree2D::~KdTree2D() { deleteObstacleTree(obstacleTree_); } - -void KdTree2D::buildAgentTree(std::vector<Agent2D *> agents) { - agents_.swap(agents); - - if (!agents_.empty()) { - agentTree_.resize(2 * agents_.size() - 1); - buildAgentTreeRecursive(0, agents_.size(), 0); - } -} - -void KdTree2D::buildAgentTreeRecursive(std::size_t begin, std::size_t end, - std::size_t node) { - agentTree_[node].begin = begin; - agentTree_[node].end = end; - agentTree_[node].minX = agentTree_[node].maxX = agents_[begin]->position_.x(); - agentTree_[node].minY = agentTree_[node].maxY = agents_[begin]->position_.y(); - - for (std::size_t i = begin + 1U; i < end; ++i) { - agentTree_[node].maxX = - std::max(agentTree_[node].maxX, agents_[i]->position_.x()); - agentTree_[node].minX = - std::min(agentTree_[node].minX, agents_[i]->position_.x()); - agentTree_[node].maxY = - std::max(agentTree_[node].maxY, agents_[i]->position_.y()); - agentTree_[node].minY = - std::min(agentTree_[node].minY, agents_[i]->position_.y()); - } - - if (end - begin > RVO_MAX_LEAF_SIZE) { - /* No leaf node. */ - const bool isVertical = agentTree_[node].maxX - agentTree_[node].minX > - agentTree_[node].maxY - agentTree_[node].minY; - const float splitValue = - 0.5F * (isVertical ? agentTree_[node].maxX + agentTree_[node].minX - : agentTree_[node].maxY + agentTree_[node].minY); - - std::size_t left = begin; - std::size_t right = end; - - while (left < right) { - while (left < right && - (isVertical ? agents_[left]->position_.x() - : agents_[left]->position_.y()) < splitValue) { - ++left; - } - - while (right > left && - (isVertical ? agents_[right - 1U]->position_.x() - : agents_[right - 1U]->position_.y()) >= splitValue) { - --right; - } - - if (left < right) { - std::swap(agents_[left], agents_[right - 1U]); - ++left; - --right; - } - } - - if (left == begin) { - ++left; - ++right; - } - - agentTree_[node].left = node + 1U; - agentTree_[node].right = node + 2U * (left - begin); - - buildAgentTreeRecursive(begin, left, agentTree_[node].left); - buildAgentTreeRecursive(left, end, agentTree_[node].right); - } -} - -void KdTree2D::buildObstacleTree(std::vector<Obstacle2D *> obstacles) { - deleteObstacleTree(obstacleTree_); - - obstacleTree_ = buildObstacleTreeRecursive(obstacles); -} - -KdTree2D::ObstacleTreeNode *KdTree2D::buildObstacleTreeRecursive( - const std::vector<Obstacle2D *> &obstacles) { - if (!obstacles.empty()) { - ObstacleTreeNode *const node = new ObstacleTreeNode(); - - std::size_t optimalSplit = 0U; - std::size_t minLeft = obstacles.size(); - std::size_t minRight = obstacles.size(); - - for (std::size_t i = 0U; i < obstacles.size(); ++i) { - std::size_t leftSize = 0U; - std::size_t rightSize = 0U; - - const Obstacle2D *const obstacleI1 = obstacles[i]; - const Obstacle2D *const obstacleI2 = obstacleI1->next_; - - /* Compute optimal split node. */ - for (std::size_t j = 0U; j < obstacles.size(); ++j) { - if (i != j) { - const Obstacle2D *const obstacleJ1 = obstacles[j]; - const Obstacle2D *const obstacleJ2 = obstacleJ1->next_; - - const float j1LeftOfI = leftOf(obstacleI1->point_, obstacleI2->point_, - obstacleJ1->point_); - const float j2LeftOfI = leftOf(obstacleI1->point_, obstacleI2->point_, - obstacleJ2->point_); - - if (j1LeftOfI >= -RVO2D_EPSILON && j2LeftOfI >= -RVO2D_EPSILON) { - ++leftSize; - } else if (j1LeftOfI <= RVO2D_EPSILON && j2LeftOfI <= RVO2D_EPSILON) { - ++rightSize; - } else { - ++leftSize; - ++rightSize; - } - - if (std::make_pair(std::max(leftSize, rightSize), - std::min(leftSize, rightSize)) >= - std::make_pair(std::max(minLeft, minRight), - std::min(minLeft, minRight))) { - break; - } - } - } - - if (std::make_pair(std::max(leftSize, rightSize), - std::min(leftSize, rightSize)) < - std::make_pair(std::max(minLeft, minRight), - std::min(minLeft, minRight))) { - minLeft = leftSize; - minRight = rightSize; - optimalSplit = i; - } - } - - /* Build split node. */ - std::vector<Obstacle2D *> leftObstacles(minLeft); - std::vector<Obstacle2D *> rightObstacles(minRight); - - std::size_t leftCounter = 0U; - std::size_t rightCounter = 0U; - const std::size_t i = optimalSplit; - - const Obstacle2D *const obstacleI1 = obstacles[i]; - const Obstacle2D *const obstacleI2 = obstacleI1->next_; - - for (std::size_t j = 0U; j < obstacles.size(); ++j) { - if (i != j) { - Obstacle2D *const obstacleJ1 = obstacles[j]; - Obstacle2D *const obstacleJ2 = obstacleJ1->next_; - - const float j1LeftOfI = - leftOf(obstacleI1->point_, obstacleI2->point_, obstacleJ1->point_); - const float j2LeftOfI = - leftOf(obstacleI1->point_, obstacleI2->point_, obstacleJ2->point_); - - if (j1LeftOfI >= -RVO2D_EPSILON && j2LeftOfI >= -RVO2D_EPSILON) { - leftObstacles[leftCounter++] = obstacles[j]; - } else if (j1LeftOfI <= RVO2D_EPSILON && j2LeftOfI <= RVO2D_EPSILON) { - rightObstacles[rightCounter++] = obstacles[j]; - } else { - /* Split obstacle j. */ - const float t = det(obstacleI2->point_ - obstacleI1->point_, - obstacleJ1->point_ - obstacleI1->point_) / - det(obstacleI2->point_ - obstacleI1->point_, - obstacleJ1->point_ - obstacleJ2->point_); - - const Vector2 splitPoint = - obstacleJ1->point_ + - t * (obstacleJ2->point_ - obstacleJ1->point_); - - Obstacle2D *const newObstacle = new Obstacle2D(); - newObstacle->direction_ = obstacleJ1->direction_; - newObstacle->point_ = splitPoint; - newObstacle->next_ = obstacleJ2; - newObstacle->previous_ = obstacleJ1; - newObstacle->id_ = simulator_->obstacles_.size(); - newObstacle->isConvex_ = true; - simulator_->obstacles_.push_back(newObstacle); - - obstacleJ1->next_ = newObstacle; - obstacleJ2->previous_ = newObstacle; - - if (j1LeftOfI > 0.0F) { - leftObstacles[leftCounter++] = obstacleJ1; - rightObstacles[rightCounter++] = newObstacle; - } else { - rightObstacles[rightCounter++] = obstacleJ1; - leftObstacles[leftCounter++] = newObstacle; - } - } - } - } - - node->obstacle = obstacleI1; - node->left = buildObstacleTreeRecursive(leftObstacles); - node->right = buildObstacleTreeRecursive(rightObstacles); - - return node; - } - - return NULL; -} - -void KdTree2D::computeAgentNeighbors(Agent2D *agent, float &rangeSq) const { - queryAgentTreeRecursive(agent, rangeSq, 0U); -} - -void KdTree2D::computeObstacleNeighbors(Agent2D *agent, float rangeSq) const { - queryObstacleTreeRecursive(agent, rangeSq, obstacleTree_); -} - -void KdTree2D::deleteObstacleTree(ObstacleTreeNode *node) { - if (node != NULL) { - deleteObstacleTree(node->left); - deleteObstacleTree(node->right); - delete node; - } -} - -void KdTree2D::queryAgentTreeRecursive(Agent2D *agent, float &rangeSq, - std::size_t node) const { - if (agentTree_[node].end - agentTree_[node].begin <= RVO_MAX_LEAF_SIZE) { - for (std::size_t i = agentTree_[node].begin; i < agentTree_[node].end; - ++i) { - agent->insertAgentNeighbor(agents_[i], rangeSq); - } - } else { - const float distLeftMinX = std::max( - 0.0F, agentTree_[agentTree_[node].left].minX - agent->position_.x()); - const float distLeftMaxX = std::max( - 0.0F, agent->position_.x() - agentTree_[agentTree_[node].left].maxX); - const float distLeftMinY = std::max( - 0.0F, agentTree_[agentTree_[node].left].minY - agent->position_.y()); - const float distLeftMaxY = std::max( - 0.0F, agent->position_.y() - agentTree_[agentTree_[node].left].maxY); - - const float distSqLeft = - distLeftMinX * distLeftMinX + distLeftMaxX * distLeftMaxX + - distLeftMinY * distLeftMinY + distLeftMaxY * distLeftMaxY; - - const float distRightMinX = std::max( - 0.0F, agentTree_[agentTree_[node].right].minX - agent->position_.x()); - const float distRightMaxX = std::max( - 0.0F, agent->position_.x() - agentTree_[agentTree_[node].right].maxX); - const float distRightMinY = std::max( - 0.0F, agentTree_[agentTree_[node].right].minY - agent->position_.y()); - const float distRightMaxY = std::max( - 0.0F, agent->position_.y() - agentTree_[agentTree_[node].right].maxY); - - const float distSqRight = - distRightMinX * distRightMinX + distRightMaxX * distRightMaxX + - distRightMinY * distRightMinY + distRightMaxY * distRightMaxY; - - if (distSqLeft < distSqRight) { - if (distSqLeft < rangeSq) { - queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].left); - - if (distSqRight < rangeSq) { - queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].right); - } - } - } else if (distSqRight < rangeSq) { - queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].right); - - if (distSqLeft < rangeSq) { - queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].left); - } - } - } -} - -void KdTree2D::queryObstacleTreeRecursive(Agent2D *agent, float rangeSq, - const ObstacleTreeNode *node) const { - if (node != NULL) { - const Obstacle2D *const obstacle1 = node->obstacle; - const Obstacle2D *const obstacle2 = obstacle1->next_; - - const float agentLeftOfLine = - leftOf(obstacle1->point_, obstacle2->point_, agent->position_); - - queryObstacleTreeRecursive( - agent, rangeSq, agentLeftOfLine >= 0.0F ? node->left : node->right); - - const float distSqLine = agentLeftOfLine * agentLeftOfLine / - absSq(obstacle2->point_ - obstacle1->point_); - - if (distSqLine < rangeSq) { - if (agentLeftOfLine < 0.0F) { - /* Try obstacle at this node only if agent is on right side of obstacle - * and can see obstacle. */ - agent->insertObstacleNeighbor(node->obstacle, rangeSq); - } - - /* Try other side of line. */ - queryObstacleTreeRecursive( - agent, rangeSq, agentLeftOfLine >= 0.0F ? node->right : node->left); - } - } -} - -bool KdTree2D::queryVisibility(const Vector2 &vector1, const Vector2 &vector2, - float radius) const { - return queryVisibilityRecursive(vector1, vector2, radius, obstacleTree_); -} - -bool KdTree2D::queryVisibilityRecursive(const Vector2 &vector1, - const Vector2 &vector2, float radius, - const ObstacleTreeNode *node) const { - if (node != NULL) { - const Obstacle2D *const obstacle1 = node->obstacle; - const Obstacle2D *const obstacle2 = obstacle1->next_; - - const float q1LeftOfI = - leftOf(obstacle1->point_, obstacle2->point_, vector1); - const float q2LeftOfI = - leftOf(obstacle1->point_, obstacle2->point_, vector2); - const float invLengthI = - 1.0F / absSq(obstacle2->point_ - obstacle1->point_); - - if (q1LeftOfI >= 0.0F && q2LeftOfI >= 0.0F) { - return queryVisibilityRecursive(vector1, vector2, radius, node->left) && - ((q1LeftOfI * q1LeftOfI * invLengthI >= radius * radius && - q2LeftOfI * q2LeftOfI * invLengthI >= radius * radius) || - queryVisibilityRecursive(vector1, vector2, radius, node->right)); - } - - if (q1LeftOfI <= 0.0F && q2LeftOfI <= 0.0F) { - return queryVisibilityRecursive(vector1, vector2, radius, node->right) && - ((q1LeftOfI * q1LeftOfI * invLengthI >= radius * radius && - q2LeftOfI * q2LeftOfI * invLengthI >= radius * radius) || - queryVisibilityRecursive(vector1, vector2, radius, node->left)); - } - - if (q1LeftOfI >= 0.0F && q2LeftOfI <= 0.0F) { - /* One can see through obstacle from left to right. */ - return queryVisibilityRecursive(vector1, vector2, radius, node->left) && - queryVisibilityRecursive(vector1, vector2, radius, node->right); - } - - const float point1LeftOfQ = leftOf(vector1, vector2, obstacle1->point_); - const float point2LeftOfQ = leftOf(vector1, vector2, obstacle2->point_); - const float invLengthQ = 1.0F / absSq(vector2 - vector1); - - return point1LeftOfQ * point2LeftOfQ >= 0.0F && - point1LeftOfQ * point1LeftOfQ * invLengthQ > radius * radius && - point2LeftOfQ * point2LeftOfQ * invLengthQ > radius * radius && - queryVisibilityRecursive(vector1, vector2, radius, node->left) && - queryVisibilityRecursive(vector1, vector2, radius, node->right); - } - - return true; -} -} /* namespace RVO2D */ diff --git a/thirdparty/rvo2/rvo2_2d/KdTree2d.cpp b/thirdparty/rvo2/rvo2_2d/KdTree2d.cpp new file mode 100644 index 0000000000..184bc74fe2 --- /dev/null +++ b/thirdparty/rvo2/rvo2_2d/KdTree2d.cpp @@ -0,0 +1,357 @@ +/* + * KdTree2d.cpp + * RVO2 Library + * + * Copyright 2008 University of North Carolina at Chapel Hill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Please send all bug reports to <geom@cs.unc.edu>. + * + * The authors may be contacted via: + * + * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha + * Dept. of Computer Science + * 201 S. Columbia St. + * Frederick P. Brooks, Jr. Computer Science Bldg. + * Chapel Hill, N.C. 27599-3175 + * United States of America + * + * <http://gamma.cs.unc.edu/RVO2/> + */ + +#include "KdTree2d.h" + +#include "Agent2d.h" +#include "RVOSimulator2d.h" +#include "Obstacle2d.h" + +namespace RVO2D { + KdTree2D::KdTree2D(RVOSimulator2D *sim) : obstacleTree_(NULL), sim_(sim) { } + + KdTree2D::~KdTree2D() + { + deleteObstacleTree(obstacleTree_); + } + + void KdTree2D::buildAgentTree(std::vector<Agent2D *> agents) + { + agents_.swap(agents); + + if (!agents_.empty()) { + agentTree_.resize(2 * agents_.size() - 1); + buildAgentTreeRecursive(0, agents_.size(), 0); + } + } + + void KdTree2D::buildAgentTreeRecursive(size_t begin, size_t end, size_t node) + { + agentTree_[node].begin = begin; + agentTree_[node].end = end; + agentTree_[node].minX = agentTree_[node].maxX = agents_[begin]->position_.x(); + agentTree_[node].minY = agentTree_[node].maxY = agents_[begin]->position_.y(); + + for (size_t i = begin + 1; i < end; ++i) { + agentTree_[node].maxX = std::max(agentTree_[node].maxX, agents_[i]->position_.x()); + agentTree_[node].minX = std::min(agentTree_[node].minX, agents_[i]->position_.x()); + agentTree_[node].maxY = std::max(agentTree_[node].maxY, agents_[i]->position_.y()); + agentTree_[node].minY = std::min(agentTree_[node].minY, agents_[i]->position_.y()); + } + + if (end - begin > MAX_LEAF_SIZE) { + /* No leaf node. */ + const bool isVertical = (agentTree_[node].maxX - agentTree_[node].minX > agentTree_[node].maxY - agentTree_[node].minY); + const float splitValue = (isVertical ? 0.5f * (agentTree_[node].maxX + agentTree_[node].minX) : 0.5f * (agentTree_[node].maxY + agentTree_[node].minY)); + + size_t left = begin; + size_t right = end; + + while (left < right) { + while (left < right && (isVertical ? agents_[left]->position_.x() : agents_[left]->position_.y()) < splitValue) { + ++left; + } + + while (right > left && (isVertical ? agents_[right - 1]->position_.x() : agents_[right - 1]->position_.y()) >= splitValue) { + --right; + } + + if (left < right) { + std::swap(agents_[left], agents_[right - 1]); + ++left; + --right; + } + } + + if (left == begin) { + ++left; + ++right; + } + + agentTree_[node].left = node + 1; + agentTree_[node].right = node + 2 * (left - begin); + + buildAgentTreeRecursive(begin, left, agentTree_[node].left); + buildAgentTreeRecursive(left, end, agentTree_[node].right); + } + } + + void KdTree2D::buildObstacleTree(std::vector<Obstacle2D *> obstacles) + { + deleteObstacleTree(obstacleTree_); + + obstacleTree_ = buildObstacleTreeRecursive(obstacles); + } + + + KdTree2D::ObstacleTreeNode *KdTree2D::buildObstacleTreeRecursive(const std::vector<Obstacle2D *> &obstacles) + { + if (obstacles.empty()) { + return NULL; + } + else { + ObstacleTreeNode *const node = new ObstacleTreeNode; + + size_t optimalSplit = 0; + size_t minLeft = obstacles.size(); + size_t minRight = obstacles.size(); + + for (size_t i = 0; i < obstacles.size(); ++i) { + size_t leftSize = 0; + size_t rightSize = 0; + + const Obstacle2D *const obstacleI1 = obstacles[i]; + const Obstacle2D *const obstacleI2 = obstacleI1->nextObstacle_; + + /* Compute optimal split node. */ + for (size_t j = 0; j < obstacles.size(); ++j) { + if (i == j) { + continue; + } + + const Obstacle2D *const obstacleJ1 = obstacles[j]; + const Obstacle2D *const obstacleJ2 = obstacleJ1->nextObstacle_; + + const float j1LeftOfI = leftOf(obstacleI1->point_, obstacleI2->point_, obstacleJ1->point_); + const float j2LeftOfI = leftOf(obstacleI1->point_, obstacleI2->point_, obstacleJ2->point_); + + if (j1LeftOfI >= -RVO_EPSILON && j2LeftOfI >= -RVO_EPSILON) { + ++leftSize; + } + else if (j1LeftOfI <= RVO_EPSILON && j2LeftOfI <= RVO_EPSILON) { + ++rightSize; + } + else { + ++leftSize; + ++rightSize; + } + + if (std::make_pair(std::max(leftSize, rightSize), std::min(leftSize, rightSize)) >= std::make_pair(std::max(minLeft, minRight), std::min(minLeft, minRight))) { + break; + } + } + + if (std::make_pair(std::max(leftSize, rightSize), std::min(leftSize, rightSize)) < std::make_pair(std::max(minLeft, minRight), std::min(minLeft, minRight))) { + minLeft = leftSize; + minRight = rightSize; + optimalSplit = i; + } + } + + /* Build split node. */ + std::vector<Obstacle2D *> leftObstacles(minLeft); + std::vector<Obstacle2D *> rightObstacles(minRight); + + size_t leftCounter = 0; + size_t rightCounter = 0; + const size_t i = optimalSplit; + + const Obstacle2D *const obstacleI1 = obstacles[i]; + const Obstacle2D *const obstacleI2 = obstacleI1->nextObstacle_; + + for (size_t j = 0; j < obstacles.size(); ++j) { + if (i == j) { + continue; + } + + Obstacle2D *const obstacleJ1 = obstacles[j]; + Obstacle2D *const obstacleJ2 = obstacleJ1->nextObstacle_; + + const float j1LeftOfI = leftOf(obstacleI1->point_, obstacleI2->point_, obstacleJ1->point_); + const float j2LeftOfI = leftOf(obstacleI1->point_, obstacleI2->point_, obstacleJ2->point_); + + if (j1LeftOfI >= -RVO_EPSILON && j2LeftOfI >= -RVO_EPSILON) { + leftObstacles[leftCounter++] = obstacles[j]; + } + else if (j1LeftOfI <= RVO_EPSILON && j2LeftOfI <= RVO_EPSILON) { + rightObstacles[rightCounter++] = obstacles[j]; + } + else { + /* Split obstacle j. */ + const float t = det(obstacleI2->point_ - obstacleI1->point_, obstacleJ1->point_ - obstacleI1->point_) / det(obstacleI2->point_ - obstacleI1->point_, obstacleJ1->point_ - obstacleJ2->point_); + + const Vector2 splitpoint = obstacleJ1->point_ + t * (obstacleJ2->point_ - obstacleJ1->point_); + + Obstacle2D *const newObstacle = new Obstacle2D(); + newObstacle->point_ = splitpoint; + newObstacle->prevObstacle_ = obstacleJ1; + newObstacle->nextObstacle_ = obstacleJ2; + newObstacle->isConvex_ = true; + newObstacle->unitDir_ = obstacleJ1->unitDir_; + + newObstacle->id_ = sim_->obstacles_.size(); + + sim_->obstacles_.push_back(newObstacle); + + obstacleJ1->nextObstacle_ = newObstacle; + obstacleJ2->prevObstacle_ = newObstacle; + + if (j1LeftOfI > 0.0f) { + leftObstacles[leftCounter++] = obstacleJ1; + rightObstacles[rightCounter++] = newObstacle; + } + else { + rightObstacles[rightCounter++] = obstacleJ1; + leftObstacles[leftCounter++] = newObstacle; + } + } + } + + node->obstacle = obstacleI1; + node->left = buildObstacleTreeRecursive(leftObstacles); + node->right = buildObstacleTreeRecursive(rightObstacles); + return node; + } + } + + void KdTree2D::computeAgentNeighbors(Agent2D *agent, float &rangeSq) const + { + queryAgentTreeRecursive(agent, rangeSq, 0); + } + + void KdTree2D::computeObstacleNeighbors(Agent2D *agent, float rangeSq) const + { + queryObstacleTreeRecursive(agent, rangeSq, obstacleTree_); + } + + void KdTree2D::deleteObstacleTree(ObstacleTreeNode *node) + { + if (node != NULL) { + deleteObstacleTree(node->left); + deleteObstacleTree(node->right); + delete node; + } + } + + void KdTree2D::queryAgentTreeRecursive(Agent2D *agent, float &rangeSq, size_t node) const + { + if (agentTree_[node].end - agentTree_[node].begin <= MAX_LEAF_SIZE) { + for (size_t i = agentTree_[node].begin; i < agentTree_[node].end; ++i) { + agent->insertAgentNeighbor(agents_[i], rangeSq); + } + } + else { + const float distSqLeft = sqr(std::max(0.0f, agentTree_[agentTree_[node].left].minX - agent->position_.x())) + sqr(std::max(0.0f, agent->position_.x() - agentTree_[agentTree_[node].left].maxX)) + sqr(std::max(0.0f, agentTree_[agentTree_[node].left].minY - agent->position_.y())) + sqr(std::max(0.0f, agent->position_.y() - agentTree_[agentTree_[node].left].maxY)); + + const float distSqRight = sqr(std::max(0.0f, agentTree_[agentTree_[node].right].minX - agent->position_.x())) + sqr(std::max(0.0f, agent->position_.x() - agentTree_[agentTree_[node].right].maxX)) + sqr(std::max(0.0f, agentTree_[agentTree_[node].right].minY - agent->position_.y())) + sqr(std::max(0.0f, agent->position_.y() - agentTree_[agentTree_[node].right].maxY)); + + if (distSqLeft < distSqRight) { + if (distSqLeft < rangeSq) { + queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].left); + + if (distSqRight < rangeSq) { + queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].right); + } + } + } + else { + if (distSqRight < rangeSq) { + queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].right); + + if (distSqLeft < rangeSq) { + queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].left); + } + } + } + + } + } + + void KdTree2D::queryObstacleTreeRecursive(Agent2D *agent, float rangeSq, const ObstacleTreeNode *node) const + { + if (node == NULL) { + return; + } + else { + const Obstacle2D *const obstacle1 = node->obstacle; + const Obstacle2D *const obstacle2 = obstacle1->nextObstacle_; + + const float agentLeftOfLine = leftOf(obstacle1->point_, obstacle2->point_, agent->position_); + + queryObstacleTreeRecursive(agent, rangeSq, (agentLeftOfLine >= 0.0f ? node->left : node->right)); + + const float distSqLine = sqr(agentLeftOfLine) / absSq(obstacle2->point_ - obstacle1->point_); + + if (distSqLine < rangeSq) { + if (agentLeftOfLine < 0.0f) { + /* + * Try obstacle at this node only if agent is on right side of + * obstacle (and can see obstacle). + */ + agent->insertObstacleNeighbor(node->obstacle, rangeSq); + } + + /* Try other side of line. */ + queryObstacleTreeRecursive(agent, rangeSq, (agentLeftOfLine >= 0.0f ? node->right : node->left)); + + } + } + } + + bool KdTree2D::queryVisibility(const Vector2 &q1, const Vector2 &q2, float radius) const + { + return queryVisibilityRecursive(q1, q2, radius, obstacleTree_); + } + + bool KdTree2D::queryVisibilityRecursive(const Vector2 &q1, const Vector2 &q2, float radius, const ObstacleTreeNode *node) const + { + if (node == NULL) { + return true; + } + else { + const Obstacle2D *const obstacle1 = node->obstacle; + const Obstacle2D *const obstacle2 = obstacle1->nextObstacle_; + + const float q1LeftOfI = leftOf(obstacle1->point_, obstacle2->point_, q1); + const float q2LeftOfI = leftOf(obstacle1->point_, obstacle2->point_, q2); + const float invLengthI = 1.0f / absSq(obstacle2->point_ - obstacle1->point_); + + if (q1LeftOfI >= 0.0f && q2LeftOfI >= 0.0f) { + return queryVisibilityRecursive(q1, q2, radius, node->left) && ((sqr(q1LeftOfI) * invLengthI >= sqr(radius) && sqr(q2LeftOfI) * invLengthI >= sqr(radius)) || queryVisibilityRecursive(q1, q2, radius, node->right)); + } + else if (q1LeftOfI <= 0.0f && q2LeftOfI <= 0.0f) { + return queryVisibilityRecursive(q1, q2, radius, node->right) && ((sqr(q1LeftOfI) * invLengthI >= sqr(radius) && sqr(q2LeftOfI) * invLengthI >= sqr(radius)) || queryVisibilityRecursive(q1, q2, radius, node->left)); + } + else if (q1LeftOfI >= 0.0f && q2LeftOfI <= 0.0f) { + /* One can see through obstacle from left to right. */ + return queryVisibilityRecursive(q1, q2, radius, node->left) && queryVisibilityRecursive(q1, q2, radius, node->right); + } + else { + const float point1LeftOfQ = leftOf(q1, q2, obstacle1->point_); + const float point2LeftOfQ = leftOf(q1, q2, obstacle2->point_); + const float invLengthQ = 1.0f / absSq(q2 - q1); + + return (point1LeftOfQ * point2LeftOfQ >= 0.0f && sqr(point1LeftOfQ) * invLengthQ > sqr(radius) && sqr(point2LeftOfQ) * invLengthQ > sqr(radius) && queryVisibilityRecursive(q1, q2, radius, node->left) && queryVisibilityRecursive(q1, q2, radius, node->right)); + } + } + } +} diff --git a/thirdparty/rvo2/rvo2_2d/KdTree2d.h b/thirdparty/rvo2/rvo2_2d/KdTree2d.h index c0e0fe9a5b..c7159eab97 100644 --- a/thirdparty/rvo2/rvo2_2d/KdTree2d.h +++ b/thirdparty/rvo2/rvo2_2d/KdTree2d.h @@ -2,14 +2,13 @@ * KdTree2d.h * RVO2 Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,162 +27,177 @@ * Chapel Hill, N.C. 27599-3175 * United States of America * - * <https://gamma.cs.unc.edu/RVO2/> + * <http://gamma.cs.unc.edu/RVO2/> */ #ifndef RVO2D_KD_TREE_H_ #define RVO2D_KD_TREE_H_ /** - * @file KdTree2d.h - * @brief Declares the KdTree2D class. + * \file KdTree2d.h + * \brief Contains the KdTree class. */ -#include <cstddef> -#include <vector> +#include "Definitions.h" namespace RVO2D { -class Agent2D; -class Obstacle2D; -class RVOSimulator2D; -class Vector2; - -/** - * @brief Defines k-D trees for agents and static obstacles in the simulation. - */ -class KdTree2D { - public: - class AgentTreeNode; - class ObstacleTreeNode; - - /** - * @brief Constructs a k-D tree instance. - * @param[in] simulator The simulator instance. - */ - explicit KdTree2D(RVOSimulator2D *simulator); - - /** - * @brief Destroys this k-D tree instance. - */ - ~KdTree2D(); - - /** - * @brief Builds an agent k-D tree. - */ - void buildAgentTree(std::vector<Agent2D *> agents); - - /** - * @brief Recursive function to build an agent k-D tree. - * @param[in] begin The beginning agent k-D tree node. - * @param[in] end The ending agent k-D tree node. - * @param[in] node The current agent k-D tree node. - */ - void buildAgentTreeRecursive(std::size_t begin, std::size_t end, - std::size_t node); - - /** - * @brief Builds an obstacle k-D tree. - */ - void buildObstacleTree(std::vector<Obstacle2D *> obstacles); - - /** - * @brief Recursive function to build an obstacle k-D tree. - * @param[in] obstacles List of obstacles from which to build the obstacle k-D - * tree. - */ - ObstacleTreeNode *buildObstacleTreeRecursive( - const std::vector<Obstacle2D *> &obstacles); - - /** - * @brief Computes the agent neighbors of the specified agent. - * @param[in] agent A pointer to the agent for which agent neighbors - * are to be computed. - * @param[in, out] rangeSq The squared range around the agent. - */ - void computeAgentNeighbors( - Agent2D *agent, float &rangeSq) const; /* NOLINT(runtime/references) */ - - /** - * @brief Computes the obstacle neighbors of the specified agent. - * @param[in] agent A pointer to the agent for which obstacle neighbors are - * to be computed. - * @param[in] rangeSq The squared range around the agent. - */ - void computeObstacleNeighbors(Agent2D *agent, float rangeSq) const; - - /** - * @brief Deletes the specified obstacle tree node. - * @param[in] node A pointer to the obstacle tree node to be deleted. - */ - void deleteObstacleTree(ObstacleTreeNode *node); - - /** - * @brief Recursive function to compute the neighbors of the specified - * agent. - * @param[in] agent A pointer to the agent for which neighbors are to be - * computed. - * @param[in,out] rangeSq The squared range around the agent. - * @param[in] node The current agent k-D tree node. - */ - void queryAgentTreeRecursive(Agent2D *agent, - float &rangeSq, /* NOLINT(runtime/references) */ - std::size_t node) const; - - /** - * @brief Recursive function to compute the neighbors of the specified - * obstacle. - * @param[in] agent A pointer to the agent for which neighbors are to be - * computed. - * @param[in,out] rangeSq The squared range around the agent. - * @param[in] node The current obstacle k-D tree node. - */ - void queryObstacleTreeRecursive(Agent2D *agent, float rangeSq, - const ObstacleTreeNode *node) const; - - /** - * @brief Queries the visibility between two points within a specified - * radius. - * @param[in] vector1 The first point between which visibility is to be - * tested. - * @param[in] vector2 The second point between which visibility is to be - * tested. - * @param[in] radius The radius within which visibility is to be tested. - * @return True if q1 and q2 are mutually visible within the radius; false - * otherwise. - */ - bool queryVisibility(const Vector2 &vector1, const Vector2 &vector2, - float radius) const; - - /** - * @brief Recursive function to query the visibility between two points - * within a specified radius. - * @param[in] vector1 The first point between which visibility is to be - * tested. - * @param[in] vector2 The second point between which visibility is to be - * tested. - * @param[in] radius The radius within which visibility is to be tested. - * @param[in] node The current obstacle k-D tree node. - * @return True if q1 and q2 are mutually visible within the radius; false - * otherwise. - */ - bool queryVisibilityRecursive(const Vector2 &vector1, const Vector2 &vector2, - float radius, - const ObstacleTreeNode *node) const; - - /* Not implemented. */ - KdTree2D(const KdTree2D &other); - - /* Not implemented. */ - KdTree2D &operator=(const KdTree2D &other); - - std::vector<Agent2D *> agents_; - std::vector<AgentTreeNode> agentTree_; - ObstacleTreeNode *obstacleTree_; - RVOSimulator2D *simulator_; - - friend class Agent2D; - friend class RVOSimulator2D; -}; -} /* namespace RVO2D */ + /** + * \brief Defines <i>k</i>d-trees for agents and static obstacles in the + * simulation. + */ + class KdTree2D { + public: + /** + * \brief Defines an agent <i>k</i>d-tree node. + */ + class AgentTreeNode { + public: + /** + * \brief The beginning node number. + */ + size_t begin; + + /** + * \brief The ending node number. + */ + size_t end; + + /** + * \brief The left node number. + */ + size_t left; + + /** + * \brief The maximum x-coordinate. + */ + float maxX; + + /** + * \brief The maximum y-coordinate. + */ + float maxY; + + /** + * \brief The minimum x-coordinate. + */ + float minX; + + /** + * \brief The minimum y-coordinate. + */ + float minY; + + /** + * \brief The right node number. + */ + size_t right; + }; + + /** + * \brief Defines an obstacle <i>k</i>d-tree node. + */ + class ObstacleTreeNode { + public: + /** + * \brief The left obstacle tree node. + */ + ObstacleTreeNode *left; + + /** + * \brief The obstacle number. + */ + const Obstacle2D *obstacle; + + /** + * \brief The right obstacle tree node. + */ + ObstacleTreeNode *right; + }; + + /** + * \brief Constructs a <i>k</i>d-tree instance. + * \param sim The simulator instance. + */ + explicit KdTree2D(RVOSimulator2D *sim); + + /** + * \brief Destroys this kd-tree instance. + */ + ~KdTree2D(); + + /** + * \brief Builds an agent <i>k</i>d-tree. + */ + void buildAgentTree(std::vector<Agent2D *> agents); + + void buildAgentTreeRecursive(size_t begin, size_t end, size_t node); + + /** + * \brief Builds an obstacle <i>k</i>d-tree. + */ + void buildObstacleTree(std::vector<Obstacle2D *> obstacles); + + ObstacleTreeNode *buildObstacleTreeRecursive(const std::vector<Obstacle2D *> & + obstacles); + + /** + * \brief Computes the agent neighbors of the specified agent. + * \param agent A pointer to the agent for which agent + * neighbors are to be computed. + * \param rangeSq The squared range around the agent. + */ + void computeAgentNeighbors(Agent2D *agent, float &rangeSq) const; + + /** + * \brief Computes the obstacle neighbors of the specified agent. + * \param agent A pointer to the agent for which obstacle + * neighbors are to be computed. + * \param rangeSq The squared range around the agent. + */ + void computeObstacleNeighbors(Agent2D *agent, float rangeSq) const; + + /** + * \brief Deletes the specified obstacle tree node. + * \param node A pointer to the obstacle tree node to be + * deleted. + */ + void deleteObstacleTree(ObstacleTreeNode *node); + + void queryAgentTreeRecursive(Agent2D *agent, float &rangeSq, + size_t node) const; + + void queryObstacleTreeRecursive(Agent2D *agent, float rangeSq, + const ObstacleTreeNode *node) const; + + /** + * \brief Queries the visibility between two points within a + * specified radius. + * \param q1 The first point between which visibility is + * to be tested. + * \param q2 The second point between which visibility is + * to be tested. + * \param radius The radius within which visibility is to be + * tested. + * \return True if q1 and q2 are mutually visible within the radius; + * false otherwise. + */ + bool queryVisibility(const Vector2 &q1, const Vector2 &q2, + float radius) const; + + bool queryVisibilityRecursive(const Vector2 &q1, const Vector2 &q2, + float radius, + const ObstacleTreeNode *node) const; + + std::vector<Agent2D *> agents_; + std::vector<AgentTreeNode> agentTree_; + ObstacleTreeNode *obstacleTree_; + RVOSimulator2D *sim_; + + static const size_t MAX_LEAF_SIZE = 10; + + friend class Agent2D; + friend class RVOSimulator2D; + }; +} #endif /* RVO2D_KD_TREE_H_ */ diff --git a/thirdparty/rvo2/rvo2_2d/Line.h b/thirdparty/rvo2/rvo2_2d/Line.h deleted file mode 100644 index 046fa82e21..0000000000 --- a/thirdparty/rvo2/rvo2_2d/Line.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Line.h - * RVO2 Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -#ifndef RVO2D_LINE_H_ -#define RVO2D_LINE_H_ - -/** - * @file Line.h - * @brief Declares the Line class. - */ - -#include "Vector2.h" - -namespace RVO2D { -/** - * @brief Defines a directed line. - */ -class Line { - public: - /** - * @brief Constructs a directed line instance. - */ - Line(); - - /** - * @brief The direction of the directed line. - */ - Vector2 direction; - - /** - * @brief A point on the directed line. - */ - Vector2 point; -}; -} /* namespace RVO2D */ - -#endif /* RVO2D_LINE_H_ */ diff --git a/thirdparty/rvo2/rvo2_2d/Obstacle2d.cc b/thirdparty/rvo2/rvo2_2d/Obstacle2d.cc deleted file mode 100644 index 0a0a5d6f26..0000000000 --- a/thirdparty/rvo2/rvo2_2d/Obstacle2d.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Obstacle2d.cpp - * RVO2 Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -/** - * @file Obstacle2d.cpp - * @brief Defines the Obstacle2D class. - */ - -#include "Obstacle2d.h" - -namespace RVO2D { -Obstacle2D::Obstacle2D() - : next_(NULL), previous_(NULL), id_(0U), isConvex_(false) {} - -Obstacle2D::~Obstacle2D() {} -} /* namespace RVO2D */ diff --git a/thirdparty/rvo2/rvo2_2d/Line.cc b/thirdparty/rvo2/rvo2_2d/Obstacle2d.cpp index 3baf841cf6..a80c8af136 100644 --- a/thirdparty/rvo2/rvo2_2d/Line.cc +++ b/thirdparty/rvo2/rvo2_2d/Obstacle2d.cpp @@ -1,15 +1,14 @@ /* - * Line.cc + * Obstacle2d.cpp * RVO2 Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,16 +27,12 @@ * Chapel Hill, N.C. 27599-3175 * United States of America * - * <https://gamma.cs.unc.edu/RVO2/> + * <http://gamma.cs.unc.edu/RVO2/> */ -/** - * @file Line.cc - * @brief Defines the Line class. - */ - -#include "Line.h" +#include "Obstacle2d.h" +#include "RVOSimulator2d.h" namespace RVO2D { -Line::Line() {} -} /* namespace RVO2D */ + Obstacle2D::Obstacle2D() : isConvex_(false), nextObstacle_(NULL), prevObstacle_(NULL), id_(0) { } +} diff --git a/thirdparty/rvo2/rvo2_2d/Obstacle2d.h b/thirdparty/rvo2/rvo2_2d/Obstacle2d.h index 8d9b61c13c..9ba5937053 100644 --- a/thirdparty/rvo2/rvo2_2d/Obstacle2d.h +++ b/thirdparty/rvo2/rvo2_2d/Obstacle2d.h @@ -2,14 +2,13 @@ * Obstacle2d.h * RVO2 Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,59 +27,46 @@ * Chapel Hill, N.C. 27599-3175 * United States of America * - * <https://gamma.cs.unc.edu/RVO2/> + * <http://gamma.cs.unc.edu/RVO2/> */ #ifndef RVO2D_OBSTACLE_H_ #define RVO2D_OBSTACLE_H_ /** - * @file Obstacle2d.h - * @brief Declares the Obstacle2D class. + * \file Obstacle2d.h + * \brief Contains the Obstacle class. */ -#include <cstddef> -#include <cstdint> - -#include "Vector2.h" +#include "Definitions.h" namespace RVO2D { -/** - * @brief Defines static obstacles in the simulation. - */ -class Obstacle2D { - public: - /** - * @brief Constructs a static obstacle instance. - */ - Obstacle2D(); - - /** - * @brief Destroys this static obstacle instance. - */ - ~Obstacle2D(); - - /* Not implemented. */ - Obstacle2D(const Obstacle2D &other); + /** + * \brief Defines static obstacles in the simulation. + */ + class Obstacle2D { + public: + /** + * \brief Constructs a static obstacle instance. + */ + Obstacle2D(); - /* Not implemented. */ - Obstacle2D &operator=(const Obstacle2D &other); + bool isConvex_; + Obstacle2D *nextObstacle_; + Vector2 point_; + Obstacle2D *prevObstacle_; + Vector2 unitDir_; - Vector2 direction_; - Vector2 point_; - Obstacle2D *next_; - Obstacle2D *previous_; - std::size_t id_; - bool isConvex_; + float height_ = 1.0; + float elevation_ = 0.0; + uint32_t avoidance_layers_ = 1; - float height_ = 1.0; - float elevation_ = 0.0; - uint32_t avoidance_layers_ = 1; + size_t id_; - friend class Agent2D; - friend class KdTree2D; - friend class RVOSimulator2D; -}; -} /* namespace RVO2D */ + friend class Agent2D; + friend class KdTree2D; + friend class RVOSimulator2D; + }; +} #endif /* RVO2D_OBSTACLE_H_ */ diff --git a/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.cc b/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.cc deleted file mode 100644 index fe44842c5c..0000000000 --- a/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.cc +++ /dev/null @@ -1,371 +0,0 @@ -/* - * RVOSimulator2d.cpp - * RVO2 Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -/** - * @file RVOSimulator2d.cpp - * @brief Defines the RVOSimulator2D class. - */ - -#include "RVOSimulator2d.h" - -#include <limits> -#include <utility> - -#include "Agent2d.h" -#include "KdTree2d.h" -#include "Line.h" -#include "Obstacle2d.h" -#include "Vector2.h" - -#ifdef _OPENMP -#include <omp.h> -#endif /* _OPENMP */ - -namespace RVO2D { -const std::size_t RVO2D_ERROR = std::numeric_limits<std::size_t>::max(); - -RVOSimulator2D::RVOSimulator2D() - : defaultAgent_(NULL), - kdTree_(new KdTree2D(this)), - globalTime_(0.0F), - timeStep_(0.0F) {} - -RVOSimulator2D::RVOSimulator2D(float timeStep, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float timeHorizonObst, float radius, float maxSpeed) - : defaultAgent_(new Agent2D()), - kdTree_(new KdTree2D(this)), - globalTime_(0.0F), - timeStep_(timeStep) { - defaultAgent_->maxNeighbors_ = maxNeighbors; - defaultAgent_->maxSpeed_ = maxSpeed; - defaultAgent_->neighborDist_ = neighborDist; - defaultAgent_->radius_ = radius; - defaultAgent_->timeHorizon_ = timeHorizon; - defaultAgent_->timeHorizonObst_ = timeHorizonObst; -} - -RVOSimulator2D::RVOSimulator2D(float timeStep, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float timeHorizonObst, float radius, float maxSpeed, - const Vector2 &velocity) - : defaultAgent_(new Agent2D()), - kdTree_(new KdTree2D(this)), - globalTime_(0.0F), - timeStep_(timeStep) { - defaultAgent_->velocity_ = velocity; - defaultAgent_->maxNeighbors_ = maxNeighbors; - defaultAgent_->maxSpeed_ = maxSpeed; - defaultAgent_->neighborDist_ = neighborDist; - defaultAgent_->radius_ = radius; - defaultAgent_->timeHorizon_ = timeHorizon; - defaultAgent_->timeHorizonObst_ = timeHorizonObst; -} - -RVOSimulator2D::~RVOSimulator2D() { - delete defaultAgent_; - delete kdTree_; - - for (std::size_t i = 0U; i < agents_.size(); ++i) { - delete agents_[i]; - } - - for (std::size_t i = 0U; i < obstacles_.size(); ++i) { - delete obstacles_[i]; - } -} - -std::size_t RVOSimulator2D::addAgent(const Vector2 &position) { - if (defaultAgent_ != NULL) { - Agent2D *const agent = new Agent2D(); - agent->position_ = position; - agent->velocity_ = defaultAgent_->velocity_; - agent->id_ = agents_.size(); - agent->maxNeighbors_ = defaultAgent_->maxNeighbors_; - agent->maxSpeed_ = defaultAgent_->maxSpeed_; - agent->neighborDist_ = defaultAgent_->neighborDist_; - agent->radius_ = defaultAgent_->radius_; - agent->timeHorizon_ = defaultAgent_->timeHorizon_; - agent->timeHorizonObst_ = defaultAgent_->timeHorizonObst_; - agents_.push_back(agent); - - return agents_.size() - 1U; - } - - return RVO2D_ERROR; -} - -std::size_t RVOSimulator2D::addAgent(const Vector2 &position, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float timeHorizonObst, float radius, - float maxSpeed) { - return addAgent(position, neighborDist, maxNeighbors, timeHorizon, - timeHorizonObst, radius, maxSpeed, Vector2()); -} - -std::size_t RVOSimulator2D::addAgent(const Vector2 &position, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float timeHorizonObst, float radius, - float maxSpeed, const Vector2 &velocity) { - Agent2D *const agent = new Agent2D(); - agent->position_ = position; - agent->velocity_ = velocity; - agent->id_ = agents_.size(); - agent->maxNeighbors_ = maxNeighbors; - agent->maxSpeed_ = maxSpeed; - agent->neighborDist_ = neighborDist; - agent->radius_ = radius; - agent->timeHorizon_ = timeHorizon; - agent->timeHorizonObst_ = timeHorizonObst; - agents_.push_back(agent); - - return agents_.size() - 1U; -} - -std::size_t RVOSimulator2D::addObstacle(const std::vector<Vector2> &vertices) { - if (vertices.size() > 1U) { - const std::size_t obstacleNo = obstacles_.size(); - - for (std::size_t i = 0U; i < vertices.size(); ++i) { - Obstacle2D *const obstacle = new Obstacle2D(); - obstacle->point_ = vertices[i]; - - if (i != 0U) { - obstacle->previous_ = obstacles_.back(); - obstacle->previous_->next_ = obstacle; - } - - if (i == vertices.size() - 1U) { - obstacle->next_ = obstacles_[obstacleNo]; - obstacle->next_->previous_ = obstacle; - } - - obstacle->direction_ = normalize( - vertices[(i == vertices.size() - 1U ? 0U : i + 1U)] - vertices[i]); - - if (vertices.size() == 2U) { - obstacle->isConvex_ = true; - } else { - obstacle->isConvex_ = - leftOf(vertices[i == 0U ? vertices.size() - 1U : i - 1U], - vertices[i], - vertices[i == vertices.size() - 1U ? 0U : i + 1U]) >= 0.0F; - } - - obstacle->id_ = obstacles_.size(); - - obstacles_.push_back(obstacle); - } - - return obstacleNo; - } - - return RVO2D_ERROR; -} - -void RVOSimulator2D::doStep() { - kdTree_->buildAgentTree(agents_); - -#ifdef _OPENMP -#pragma omp parallel for -#endif /* _OPENMP */ - for (int i = 0; i < static_cast<int>(agents_.size()); ++i) { - agents_[i]->computeNeighbors(kdTree_); - agents_[i]->computeNewVelocity(timeStep_); - } - -#ifdef _OPENMP -#pragma omp parallel for -#endif /* _OPENMP */ - for (int i = 0; i < static_cast<int>(agents_.size()); ++i) { - agents_[i]->update(timeStep_); - } - - globalTime_ += timeStep_; -} - -std::size_t RVOSimulator2D::getAgentAgentNeighbor(std::size_t agentNo, - std::size_t neighborNo) const { - return agents_[agentNo]->agentNeighbors_[neighborNo].second->id_; -} - -std::size_t RVOSimulator2D::getAgentMaxNeighbors(std::size_t agentNo) const { - return agents_[agentNo]->maxNeighbors_; -} - -float RVOSimulator2D::getAgentMaxSpeed(std::size_t agentNo) const { - return agents_[agentNo]->maxSpeed_; -} - -float RVOSimulator2D::getAgentNeighborDist(std::size_t agentNo) const { - return agents_[agentNo]->neighborDist_; -} - -std::size_t RVOSimulator2D::getAgentNumAgentNeighbors(std::size_t agentNo) const { - return agents_[agentNo]->agentNeighbors_.size(); -} - -std::size_t RVOSimulator2D::getAgentNumObstacleNeighbors( - std::size_t agentNo) const { - return agents_[agentNo]->obstacleNeighbors_.size(); -} - -std::size_t RVOSimulator2D::getAgentNumORCALines(std::size_t agentNo) const { - return agents_[agentNo]->orcaLines_.size(); -} - -std::size_t RVOSimulator2D::getAgentObstacleNeighbor( - std::size_t agentNo, std::size_t neighborNo) const { - return agents_[agentNo]->obstacleNeighbors_[neighborNo].second->id_; -} - -const Line &RVOSimulator2D::getAgentORCALine(std::size_t agentNo, - std::size_t lineNo) const { - return agents_[agentNo]->orcaLines_[lineNo]; -} - -const Vector2 &RVOSimulator2D::getAgentPosition(std::size_t agentNo) const { - return agents_[agentNo]->position_; -} - -const Vector2 &RVOSimulator2D::getAgentPrefVelocity(std::size_t agentNo) const { - return agents_[agentNo]->prefVelocity_; -} - -float RVOSimulator2D::getAgentRadius(std::size_t agentNo) const { - return agents_[agentNo]->radius_; -} - -float RVOSimulator2D::getAgentTimeHorizon(std::size_t agentNo) const { - return agents_[agentNo]->timeHorizon_; -} - -float RVOSimulator2D::getAgentTimeHorizonObst(std::size_t agentNo) const { - return agents_[agentNo]->timeHorizonObst_; -} - -const Vector2 &RVOSimulator2D::getAgentVelocity(std::size_t agentNo) const { - return agents_[agentNo]->velocity_; -} - -const Vector2 &RVOSimulator2D::getObstacleVertex(std::size_t vertexNo) const { - return obstacles_[vertexNo]->point_; -} - -std::size_t RVOSimulator2D::getNextObstacleVertexNo(std::size_t vertexNo) const { - return obstacles_[vertexNo]->next_->id_; -} - -std::size_t RVOSimulator2D::getPrevObstacleVertexNo(std::size_t vertexNo) const { - return obstacles_[vertexNo]->previous_->id_; -} - -void RVOSimulator2D::processObstacles() { kdTree_->buildObstacleTree(obstacles_); } - -bool RVOSimulator2D::queryVisibility(const Vector2 &point1, - const Vector2 &point2) const { - return kdTree_->queryVisibility(point1, point2, 0.0F); -} - -bool RVOSimulator2D::queryVisibility(const Vector2 &point1, const Vector2 &point2, - float radius) const { - return kdTree_->queryVisibility(point1, point2, radius); -} - -void RVOSimulator2D::setAgentDefaults(float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float timeHorizonObst, float radius, - float maxSpeed) { - setAgentDefaults(neighborDist, maxNeighbors, timeHorizon, timeHorizonObst, - radius, maxSpeed, Vector2()); -} - -void RVOSimulator2D::setAgentDefaults(float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float timeHorizonObst, float radius, - float maxSpeed, const Vector2 &velocity) { - if (defaultAgent_ == NULL) { - defaultAgent_ = new Agent2D(); - } - - defaultAgent_->maxNeighbors_ = maxNeighbors; - defaultAgent_->maxSpeed_ = maxSpeed; - defaultAgent_->neighborDist_ = neighborDist; - defaultAgent_->radius_ = radius; - defaultAgent_->timeHorizon_ = timeHorizon; - defaultAgent_->timeHorizonObst_ = timeHorizonObst; - defaultAgent_->velocity_ = velocity; -} - -void RVOSimulator2D::setAgentMaxNeighbors(std::size_t agentNo, - std::size_t maxNeighbors) { - agents_[agentNo]->maxNeighbors_ = maxNeighbors; -} - -void RVOSimulator2D::setAgentMaxSpeed(std::size_t agentNo, float maxSpeed) { - agents_[agentNo]->maxSpeed_ = maxSpeed; -} - -void RVOSimulator2D::setAgentNeighborDist(std::size_t agentNo, - float neighborDist) { - agents_[agentNo]->neighborDist_ = neighborDist; -} - -void RVOSimulator2D::setAgentPosition(std::size_t agentNo, - const Vector2 &position) { - agents_[agentNo]->position_ = position; -} - -void RVOSimulator2D::setAgentPrefVelocity(std::size_t agentNo, - const Vector2 &prefVelocity) { - agents_[agentNo]->prefVelocity_ = prefVelocity; -} - -void RVOSimulator2D::setAgentRadius(std::size_t agentNo, float radius) { - agents_[agentNo]->radius_ = radius; -} - -void RVOSimulator2D::setAgentTimeHorizon(std::size_t agentNo, float timeHorizon) { - agents_[agentNo]->timeHorizon_ = timeHorizon; -} - -void RVOSimulator2D::setAgentTimeHorizonObst(std::size_t agentNo, - float timeHorizonObst) { - agents_[agentNo]->timeHorizonObst_ = timeHorizonObst; -} - -void RVOSimulator2D::setAgentVelocity(std::size_t agentNo, - const Vector2 &velocity) { - agents_[agentNo]->velocity_ = velocity; -} -} /* namespace RVO2D */ diff --git a/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.cpp b/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.cpp new file mode 100644 index 0000000000..9fb1555ebc --- /dev/null +++ b/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.cpp @@ -0,0 +1,363 @@ +/* + * RVOSimulator2d.cpp + * RVO2 Library + * + * Copyright 2008 University of North Carolina at Chapel Hill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Please send all bug reports to <geom@cs.unc.edu>. + * + * The authors may be contacted via: + * + * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha + * Dept. of Computer Science + * 201 S. Columbia St. + * Frederick P. Brooks, Jr. Computer Science Bldg. + * Chapel Hill, N.C. 27599-3175 + * United States of America + * + * <http://gamma.cs.unc.edu/RVO2/> + */ + +#include "RVOSimulator2d.h" + +#include "Agent2d.h" +#include "KdTree2d.h" +#include "Obstacle2d.h" + +#ifdef _OPENMP +#include <omp.h> +#endif + +namespace RVO2D { + RVOSimulator2D::RVOSimulator2D() : defaultAgent_(NULL), globalTime_(0.0f), kdTree_(NULL), timeStep_(0.0f) + { + kdTree_ = new KdTree2D(this); + } + + RVOSimulator2D::RVOSimulator2D(float timeStep, float neighborDist, size_t maxNeighbors, float timeHorizon, float timeHorizonObst, float radius, float maxSpeed, const Vector2 &velocity) : defaultAgent_(NULL), globalTime_(0.0f), kdTree_(NULL), timeStep_(timeStep) + { + kdTree_ = new KdTree2D(this); + defaultAgent_ = new Agent2D(); + + defaultAgent_->maxNeighbors_ = maxNeighbors; + defaultAgent_->maxSpeed_ = maxSpeed; + defaultAgent_->neighborDist_ = neighborDist; + defaultAgent_->radius_ = radius; + defaultAgent_->timeHorizon_ = timeHorizon; + defaultAgent_->timeHorizonObst_ = timeHorizonObst; + defaultAgent_->velocity_ = velocity; + } + + RVOSimulator2D::~RVOSimulator2D() + { + if (defaultAgent_ != NULL) { + delete defaultAgent_; + } + + for (size_t i = 0; i < agents_.size(); ++i) { + delete agents_[i]; + } + + for (size_t i = 0; i < obstacles_.size(); ++i) { + delete obstacles_[i]; + } + + delete kdTree_; + } + + size_t RVOSimulator2D::addAgent(const Vector2 &position) + { + if (defaultAgent_ == NULL) { + return RVO2D_ERROR; + } + + Agent2D *agent = new Agent2D(); + + agent->position_ = position; + agent->maxNeighbors_ = defaultAgent_->maxNeighbors_; + agent->maxSpeed_ = defaultAgent_->maxSpeed_; + agent->neighborDist_ = defaultAgent_->neighborDist_; + agent->radius_ = defaultAgent_->radius_; + agent->timeHorizon_ = defaultAgent_->timeHorizon_; + agent->timeHorizonObst_ = defaultAgent_->timeHorizonObst_; + agent->velocity_ = defaultAgent_->velocity_; + + agent->id_ = agents_.size(); + + agents_.push_back(agent); + + return agents_.size() - 1; + } + + size_t RVOSimulator2D::addAgent(const Vector2 &position, float neighborDist, size_t maxNeighbors, float timeHorizon, float timeHorizonObst, float radius, float maxSpeed, const Vector2 &velocity) + { + Agent2D *agent = new Agent2D(); + + agent->position_ = position; + agent->maxNeighbors_ = maxNeighbors; + agent->maxSpeed_ = maxSpeed; + agent->neighborDist_ = neighborDist; + agent->radius_ = radius; + agent->timeHorizon_ = timeHorizon; + agent->timeHorizonObst_ = timeHorizonObst; + agent->velocity_ = velocity; + + agent->id_ = agents_.size(); + + agents_.push_back(agent); + + return agents_.size() - 1; + } + + size_t RVOSimulator2D::addObstacle(const std::vector<Vector2> &vertices) + { + if (vertices.size() < 2) { + return RVO2D_ERROR; + } + + const size_t obstacleNo = obstacles_.size(); + + for (size_t i = 0; i < vertices.size(); ++i) { + Obstacle2D *obstacle = new Obstacle2D(); + obstacle->point_ = vertices[i]; + + if (i != 0) { + obstacle->prevObstacle_ = obstacles_.back(); + obstacle->prevObstacle_->nextObstacle_ = obstacle; + } + + if (i == vertices.size() - 1) { + obstacle->nextObstacle_ = obstacles_[obstacleNo]; + obstacle->nextObstacle_->prevObstacle_ = obstacle; + } + + obstacle->unitDir_ = normalize(vertices[(i == vertices.size() - 1 ? 0 : i + 1)] - vertices[i]); + + if (vertices.size() == 2) { + obstacle->isConvex_ = true; + } + else { + obstacle->isConvex_ = (leftOf(vertices[(i == 0 ? vertices.size() - 1 : i - 1)], vertices[i], vertices[(i == vertices.size() - 1 ? 0 : i + 1)]) >= 0.0f); + } + + obstacle->id_ = obstacles_.size(); + + obstacles_.push_back(obstacle); + } + + return obstacleNo; + } + + void RVOSimulator2D::doStep() + { + kdTree_->buildAgentTree(agents_); + + for (int i = 0; i < static_cast<int>(agents_.size()); ++i) { + agents_[i]->computeNeighbors(this); + agents_[i]->computeNewVelocity(this); + } + + for (int i = 0; i < static_cast<int>(agents_.size()); ++i) { + agents_[i]->update(this); + } + + globalTime_ += timeStep_; + } + + size_t RVOSimulator2D::getAgentAgentNeighbor(size_t agentNo, size_t neighborNo) const + { + return agents_[agentNo]->agentNeighbors_[neighborNo].second->id_; + } + + size_t RVOSimulator2D::getAgentMaxNeighbors(size_t agentNo) const + { + return agents_[agentNo]->maxNeighbors_; + } + + float RVOSimulator2D::getAgentMaxSpeed(size_t agentNo) const + { + return agents_[agentNo]->maxSpeed_; + } + + float RVOSimulator2D::getAgentNeighborDist(size_t agentNo) const + { + return agents_[agentNo]->neighborDist_; + } + + size_t RVOSimulator2D::getAgentNumAgentNeighbors(size_t agentNo) const + { + return agents_[agentNo]->agentNeighbors_.size(); + } + + size_t RVOSimulator2D::getAgentNumObstacleNeighbors(size_t agentNo) const + { + return agents_[agentNo]->obstacleNeighbors_.size(); + } + + size_t RVOSimulator2D::getAgentNumORCALines(size_t agentNo) const + { + return agents_[agentNo]->orcaLines_.size(); + } + + size_t RVOSimulator2D::getAgentObstacleNeighbor(size_t agentNo, size_t neighborNo) const + { + return agents_[agentNo]->obstacleNeighbors_[neighborNo].second->id_; + } + + const Line &RVOSimulator2D::getAgentORCALine(size_t agentNo, size_t lineNo) const + { + return agents_[agentNo]->orcaLines_[lineNo]; + } + + const Vector2 &RVOSimulator2D::getAgentPosition(size_t agentNo) const + { + return agents_[agentNo]->position_; + } + + const Vector2 &RVOSimulator2D::getAgentPrefVelocity(size_t agentNo) const + { + return agents_[agentNo]->prefVelocity_; + } + + float RVOSimulator2D::getAgentRadius(size_t agentNo) const + { + return agents_[agentNo]->radius_; + } + + float RVOSimulator2D::getAgentTimeHorizon(size_t agentNo) const + { + return agents_[agentNo]->timeHorizon_; + } + + float RVOSimulator2D::getAgentTimeHorizonObst(size_t agentNo) const + { + return agents_[agentNo]->timeHorizonObst_; + } + + const Vector2 &RVOSimulator2D::getAgentVelocity(size_t agentNo) const + { + return agents_[agentNo]->velocity_; + } + + float RVOSimulator2D::getGlobalTime() const + { + return globalTime_; + } + + size_t RVOSimulator2D::getNumAgents() const + { + return agents_.size(); + } + + size_t RVOSimulator2D::getNumObstacleVertices() const + { + return obstacles_.size(); + } + + const Vector2 &RVOSimulator2D::getObstacleVertex(size_t vertexNo) const + { + return obstacles_[vertexNo]->point_; + } + + size_t RVOSimulator2D::getNextObstacleVertexNo(size_t vertexNo) const + { + return obstacles_[vertexNo]->nextObstacle_->id_; + } + + size_t RVOSimulator2D::getPrevObstacleVertexNo(size_t vertexNo) const + { + return obstacles_[vertexNo]->prevObstacle_->id_; + } + + float RVOSimulator2D::getTimeStep() const + { + return timeStep_; + } + + void RVOSimulator2D::processObstacles() + { + kdTree_->buildObstacleTree(obstacles_); + } + + bool RVOSimulator2D::queryVisibility(const Vector2 &point1, const Vector2 &point2, float radius) const + { + return kdTree_->queryVisibility(point1, point2, radius); + } + + void RVOSimulator2D::setAgentDefaults(float neighborDist, size_t maxNeighbors, float timeHorizon, float timeHorizonObst, float radius, float maxSpeed, const Vector2 &velocity) + { + if (defaultAgent_ == NULL) { + defaultAgent_ = new Agent2D(); + } + + defaultAgent_->maxNeighbors_ = maxNeighbors; + defaultAgent_->maxSpeed_ = maxSpeed; + defaultAgent_->neighborDist_ = neighborDist; + defaultAgent_->radius_ = radius; + defaultAgent_->timeHorizon_ = timeHorizon; + defaultAgent_->timeHorizonObst_ = timeHorizonObst; + defaultAgent_->velocity_ = velocity; + } + + void RVOSimulator2D::setAgentMaxNeighbors(size_t agentNo, size_t maxNeighbors) + { + agents_[agentNo]->maxNeighbors_ = maxNeighbors; + } + + void RVOSimulator2D::setAgentMaxSpeed(size_t agentNo, float maxSpeed) + { + agents_[agentNo]->maxSpeed_ = maxSpeed; + } + + void RVOSimulator2D::setAgentNeighborDist(size_t agentNo, float neighborDist) + { + agents_[agentNo]->neighborDist_ = neighborDist; + } + + void RVOSimulator2D::setAgentPosition(size_t agentNo, const Vector2 &position) + { + agents_[agentNo]->position_ = position; + } + + void RVOSimulator2D::setAgentPrefVelocity(size_t agentNo, const Vector2 &prefVelocity) + { + agents_[agentNo]->prefVelocity_ = prefVelocity; + } + + void RVOSimulator2D::setAgentRadius(size_t agentNo, float radius) + { + agents_[agentNo]->radius_ = radius; + } + + void RVOSimulator2D::setAgentTimeHorizon(size_t agentNo, float timeHorizon) + { + agents_[agentNo]->timeHorizon_ = timeHorizon; + } + + void RVOSimulator2D::setAgentTimeHorizonObst(size_t agentNo, float timeHorizonObst) + { + agents_[agentNo]->timeHorizonObst_ = timeHorizonObst; + } + + void RVOSimulator2D::setAgentVelocity(size_t agentNo, const Vector2 &velocity) + { + agents_[agentNo]->velocity_ = velocity; + } + + void RVOSimulator2D::setTimeStep(float timeStep) + { + timeStep_ = timeStep; + } +} diff --git a/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.h b/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.h index 638c357437..e074e0fe0e 100644 --- a/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.h +++ b/thirdparty/rvo2/rvo2_2d/RVOSimulator2d.h @@ -1,15 +1,14 @@ /* - * RVOSimulator.h + * RVOSimulator2d.h * RVO2 Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,638 +27,566 @@ * Chapel Hill, N.C. 27599-3175 * United States of America * - * <https://gamma.cs.unc.edu/RVO2/> + * <http://gamma.cs.unc.edu/RVO2/> */ #ifndef RVO2D_RVO_SIMULATOR_H_ #define RVO2D_RVO_SIMULATOR_H_ /** - * @file RVOSimulator2d.h - * @brief Declares and defines the RVOSimulator2D class. + * \file RVOSimulator2d.h + * \brief Contains the RVOSimulator2D class. */ #include <cstddef> +#include <limits> #include <vector> +#include "Vector2.h" namespace RVO2D { -class Agent2D; -class KdTree2D; -class Line; -class Obstacle2D; -class Vector2; - -/** - * @relates RVOSimulator2D - * @brief Error value. A value equal to the largest unsigned integer that is - * returned in case of an error by functions in RVO::RVOSimulator. - */ -extern const std::size_t RVO2D_ERROR; - -/** - * @brief Defines the simulation. The main class of the library that contains - * all simulation functionality. - */ -class RVOSimulator2D { - public: - /** - * @brief Constructs a simulator instance. - */ - RVOSimulator2D(); - - /** - * @brief Constructs a simulator instance and sets the default - * properties for any new agent that is added. - * @param[in] timeStep The time step of the simulation. Must be - * positive. - * @param[in] neighborDist The default maximum distance center-point to - * center-point to other agents a new agent takes - * into account in the navigation. The larger this - * number, the longer he running time of the - * simulation. If the number is too low, the - * simulation will not be safe. Must be - * non-negative. - * @param[in] maxNeighbors The default maximum number of other agents a - * new agent takes into account in the navigation. - * The larger this number, the longer the running - * time of the simulation. If the number is too - * low, the simulation will not be safe. - * @param[in] timeHorizon The default minimal amount of time for which a - * new agent's velocities that are computed by the - * simulation are safe with respect to other - * agents. The larger this number, the sooner an - * agent will respond to the presence of other - * agents, but the less freedom the agent has in - * choosing its velocities. Must be positive. - * @param[in] timeHorizonObst The default minimal amount of time for which a - * new agent's velocities that are computed by the - * simulation are safe with respect to obstacles. - * The larger this number, the sooner an agent will - * respond to the presence of obstacles, but the - * less freedom the agent has in choosing its - * velocities. Must be positive. - * @param[in] radius The default radius of a new agent. Must be - * non-negative. - * @param[in] maxSpeed The default maximum speed of a new agent. Must - * be non-negative. - */ - RVOSimulator2D(float timeStep, float neighborDist, std::size_t maxNeighbors, - float timeHorizon, float timeHorizonObst, float radius, - float maxSpeed); - - /** - * @brief Constructs a simulator instance and sets the default properties - * for any new agent that is added. - * @param[in] timeStep The time step of the simulation. Must be - * positive. - * @param[in] neighborDist The default maximum distance center-point to - * center-point to other agents a new agent takes - * into account in the navigation. The larger this - * number, the longer he running time of the - * simulation. If the number is too low, the - * simulation will not be safe. Must be - * non-negative. - * @param[in] maxNeighbors The default maximum number of other agents a new - * agent takes into account in the navigation. The - * larger this number, the longer the running time - * of the simulation. If the number is too low, the - * simulation will not be safe. - * @param[in] timeHorizon The default minimal amount of time for which a - * new agent's velocities that are computed by the - * simulation are safe with respect to other - * agents. The larger this number, the sooner an - * agent will respond to the presence of other - * agents, but the less freedom the agent has in - * choosing its velocities. Must be positive. - * @param[in] timeHorizonObst The default minimal amount of time for which a - * new agent's velocities that are computed by the - * simulation are safe with respect to obstacles. - * The larger this number, the sooner an agent will - * respond to the presence of obstacles, but the - * less freedom the agent has in choosing its - * velocities. Must be positive. - * @param[in] radius The default radius of a new agent. Must be - * non-negative. - * @param[in] maxSpeed The default maximum speed of a new agent. Must - * be non-negative. - * @param[in] velocity The default initial two-dimensional linear - * velocity of a new agent. - */ - RVOSimulator2D(float timeStep, float neighborDist, std::size_t maxNeighbors, - float timeHorizon, float timeHorizonObst, float radius, - float maxSpeed, const Vector2 &velocity); - - /** - * @brief Destroys this simulator instance. - */ - ~RVOSimulator2D(); - - /** - * @brief Adds a new agent with default properties to the simulation. - * @param[in] position The two-dimensional starting position of this agent. - * @return The number of the agent, or RVO::RVO2D_ERROR when the agent - * defaults have not been set. - */ - std::size_t addAgent(const Vector2 &position); - - /** - * @brief Adds a new agent to the simulation. - * @param[in] position The two-dimensional starting position of this - * agent. - * @param[in] neighborDist The maximum distance center-point to - * center-point to other agents this agent takes - * into account in the navigation. The larger this - * number, the longer the running time of the - * simulation. If the number is too low, the - * simulation will not be safe. Must be - * non-negative. - * @param[in] maxNeighbors The maximum number of other agents this agent - * takes into account in the navigation. The larger - * this number, the longer the running time of the - * simulation. If the number is too low, the - * simulation will not be safe. - * @param[in] timeHorizon The minimal amount of time for which this - * agent's velocities that are computed by the - * simulation are safe with respect to other - * agents. The larger this number, the sooner this - * agent will respond to the presence of other - * agents, but the less freedom this agent has in - * choosing its velocities. Must be positive. - * @param[in] timeHorizonObst The minimal amount of time for which this - * agent's velocities that are computed by the - * simulation are safe with respect to obstacles - * The larger this number, the sooner this agent - * will respond to the presence of obstacles, but - * the less freedom this agent has in choosing its - * velocities. Must be positive. - * @param[in] radius The radius of this agent. Must be non-negative. - * @param[in] maxSpeed The maximum speed of this agent. Must be - * non-negative. - * @return The number of the agent. - */ - std::size_t addAgent(const Vector2 &position, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float timeHorizonObst, float radius, float maxSpeed); - - /** - * @brief Adds a new agent to the simulation. - * @param[in] position The two-dimensional starting position of this - * agent. - * @param[in] neighborDist The maximum distance center-point to - * center-point to other agents this agent takes - * into account in the navigation. The larger this - * number, the longer the running time of the - * simulation. If the number is too low, the - * simulation will not be safe. Must be - * non-negative. - * @param[in] maxNeighbors The maximum number of other agents this agent - * takes into account in the navigation. The larger - * this number, the longer the running time of the - * simulation. If the number is too low, the - * simulation will not be safe. - * @param[in] timeHorizon The minimal amount of time for which this - * agent's velocities that are computed by the - * simulation are safe with respect to other - * agents. The larger this number, the sooner this - * agent will respond to the presence of other - * agents, but the less freedom this agent has in - * choosing its velocities. Must be positive. - * @param[in] timeHorizonObst The minimal amount of time for which this - * agent's velocities that are computed by the - * simulation are safe with respect to obstacles. - * The larger this number, the sooner this agent - * will respond to the presence of obstacles, but - * the less freedom this agent has in choosing its - * velocities. Must be positive. - * @param[in] radius The radius of this agent. Must be non-negative. - * @param[in] maxSpeed The maximum speed of this agent. Must be - * non-negative. - * @param[in] velocity The initial two-dimensional linear velocity of - * this agent. - * @return The number of the agent. - */ - std::size_t addAgent(const Vector2 &position, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float timeHorizonObst, float radius, float maxSpeed, - const Vector2 &velocity); - - /** - * @brief Adds a new obstacle to the simulation. - * @param[in] vertices List of the vertices of the polygonal obstacle in - * counterclockwise order. - * @return The number of the first vertex of the obstacle, or - * RVO::RVO2D_ERROR when the number of vertices is less than two. - * @note To add a "negative" obstacle, e.g., a bounding polygon around - * the environment, the vertices should be listed in clockwise - * order. - */ - std::size_t addObstacle(const std::vector<Vector2> &vertices); - - /** - * @brief Lets the simulator perform a simulation step and updates the - * two-dimensional position and two-dimensional velocity of each agent. - */ - void doStep(); - - /** - * @brief Returns the specified agent neighbor of the specified agent. - * @param[in] agentNo The number of the agent whose agent neighbor is to be - * retrieved. - * @param[in] neighborNo The number of the agent neighbor to be retrieved. - * @return The number of the neighboring agent. - */ - std::size_t getAgentAgentNeighbor(std::size_t agentNo, - std::size_t neighborNo) const; - - /** - * @brief Returns the maximum neighbor count of a specified agent. - * @param[in] agentNo The number of the agent whose maximum neighbor count is - * to be retrieved. - * @return The present maximum neighbor count of the agent. - */ - std::size_t getAgentMaxNeighbors(std::size_t agentNo) const; - - /** - * @brief Returns the maximum speed of a specified agent. - * @param[in] agentNo The number of the agent whose maximum speed is to be - * retrieved. - * @return The present maximum speed of the agent. - */ - float getAgentMaxSpeed(std::size_t agentNo) const; - - /** - * @brief Returns the maximum neighbor distance of a specified agent. - * @param[in] agentNo The number of the agent whose maximum neighbor distance - * is to be retrieved. - * @return The present maximum neighbor distance of the agent. - */ - float getAgentNeighborDist(std::size_t agentNo) const; - - /** - * @brief Returns the count of agent neighbors taken into account to - * compute the current velocity for the specified agent. - * @param[in] agentNo The number of the agent whose count of agent neighbors - * is to be retrieved. - * @return The count of agent neighbors taken into account to compute the - * current velocity for the specified agent. - */ - std::size_t getAgentNumAgentNeighbors(std::size_t agentNo) const; - - /** - * @brief Returns the count of obstacle neighbors taken into account to - * compute the current velocity for the specified agent. - * @param[in] agentNo The number of the agent whose count of obstacle - * neighbors is to be retrieved. - * @return The count of obstacle neighbors taken into account to compute - * the current velocity for the specified agent. - */ - std::size_t getAgentNumObstacleNeighbors(std::size_t agentNo) const; - - /** - * @brief Returns the count of ORCA constraints used to compute the - * current velocity for the specified agent. - * @param[in] agentNo The number of the agent whose count of ORCA constraints - * is to be retrieved. - * @return The count of ORCA constraints used to compute the current - * velocity for the specified agent. - */ - std::size_t getAgentNumORCALines(std::size_t agentNo) const; - - /** - * @brief Returns the specified obstacle neighbor of the specified agent. - * @param[in] agentNo The number of the agent whose obstacle neighbor is to - * be retrieved. - * @param[in] neighborNo The number of the obstacle neighbor to be retrieved. - * @return The number of the first vertex of the neighboring obstacle edge. - */ - std::size_t getAgentObstacleNeighbor(std::size_t agentNo, - std::size_t neighborNo) const; - - /** - * @brief Returns the specified ORCA constraint of the specified agent. - * @param[in] agentNo The number of the agent whose ORCA constraint is to be - * retrieved. - * @param[in] lineNo The number of the ORCA constraint to be retrieved. - * @return A line representing the specified ORCA constraint. - * @note The half-plane to the left of the line is the region of - * permissible velocities with respect to the specified ORCA - * constraint. - */ - const Line &getAgentORCALine(std::size_t agentNo, std::size_t lineNo) const; - - /** - * @brief Returns the two-dimensional position of a specified agent. - * @param[in] agentNo The number of the agent whose two-dimensional position - * is to be retrieved. - * @return The present two-dimensional position of the center of the agent. - */ - const Vector2 &getAgentPosition(std::size_t agentNo) const; - - /** - * @brief Returns the two-dimensional preferred velocity of a specified - * agent. - * @param[in] agentNo The number of the agent whose two-dimensional preferred - * velocity is to be retrieved. - * @return The present two-dimensional preferred velocity of the agent. - */ - const Vector2 &getAgentPrefVelocity(std::size_t agentNo) const; - - /** - * @brief Returns the radius of a specified agent. - * @param[in] agentNo The number of the agent whose radius is to be retrieved. - * @return The present radius of the agent. - */ - float getAgentRadius(std::size_t agentNo) const; - - /** - * @brief Returns the time horizon of a specified agent. - * @param[in] agentNo The number of the agent whose time horizon is to be - * retrieved. - * @return The present time horizon of the agent. - */ - float getAgentTimeHorizon(std::size_t agentNo) const; - - /** - * @brief Returns the time horizon with respect to obstacles of a - * specified agent. - * @param[in] agentNo The number of the agent whose time horizon with respect - * to obstacles is to be retrieved. - * @return The present time horizon with respect to obstacles of the agent. - */ - float getAgentTimeHorizonObst(std::size_t agentNo) const; - - /** - * @brief Returns the two-dimensional linear velocity of a specified - * agent. - * @param[in] agentNo The number of the agent whose two-dimensional linear - * velocity is to be retrieved. - * @return The present two-dimensional linear velocity of the agent. - */ - const Vector2 &getAgentVelocity(std::size_t agentNo) const; - - /** - * @brief Returns the global time of the simulation. - * @return The present global time of the simulation (zero initially). - */ - float getGlobalTime() const { return globalTime_; } - - /** - * @brief Returns the count of agents in the simulation. - * @return The count of agents in the simulation. - */ - std::size_t getNumAgents() const { return agents_.size(); } - - /** - * @brief Returns the count of obstacle vertices in the simulation. - * @return The count of obstacle vertices in the simulation. - */ - std::size_t getNumObstacleVertices() const { return obstacles_.size(); } - - /** - * @brief Returns the two-dimensional position of a specified obstacle - * vertex. - * @param[in] vertexNo The number of the obstacle vertex to be retrieved. - * @return The two-dimensional position of the specified obstacle vertex. - */ - const Vector2 &getObstacleVertex(std::size_t vertexNo) const; - - /** - * @brief Returns the number of the obstacle vertex succeeding the - * specified obstacle vertex in its polygon. - * @param[in] vertexNo The number of the obstacle vertex whose successor is to - * be retrieved. - * @return The number of the obstacle vertex succeeding the specified - * obstacle vertex in its polygon. - */ - std::size_t getNextObstacleVertexNo(std::size_t vertexNo) const; - - /** - * @brief Returns the number of the obstacle vertex preceding the - * specified obstacle vertex in its polygon. - * @param[in] vertexNo The number of the obstacle vertex whose predecessor is - * to be retrieved. - * @return The number of the obstacle vertex preceding the specified - * obstacle vertex in its polygon. - */ - std::size_t getPrevObstacleVertexNo(std::size_t vertexNo) const; - - /** - * @brief Returns the time step of the simulation. - * @return The present time step of the simulation. - */ - float getTimeStep() const { return timeStep_; } - - /** - * @brief Processes the obstacles that have been added so that they are - * accounted for in the simulation. - * @note Obstacles added to the simulation after this function has been - * called are not accounted for in the simulation. - */ - void processObstacles(); - - /** - * @brief Performs a visibility query between the two specified points - * with respect to the obstacles - * @param[in] point1 The first point of the query. - * @param[in] point2 The second point of the query. - * @return A boolean specifying whether the two points are mutually - * visible. Returns true when the obstacles have not been - * processed. - */ - bool queryVisibility(const Vector2 &point1, const Vector2 &point2) const; - - /** - * @brief Performs a visibility query between the two specified points - * with respect to the obstacles - * @param[in] point1 The first point of the query. - * @param[in] point2 The second point of the query. - * @param[in] radius The minimal distance between the line connecting the two - * points and the obstacles in order for the points to be - * mutually visible. Must be non-negative. - * @return A boolean specifying whether the two points are mutually - * visible. Returns true when the obstacles have not been - * processed. - */ - bool queryVisibility(const Vector2 &point1, const Vector2 &point2, - float radius) const; - - /** - * @brief Sets the default properties for any new agent that is added. - * @param[in] neighborDist The default maximum distance center-point to - * center-point to other agents a new agent takes - * into account in the navigation. The larger this - * number, the longer he running time of the - * simulation. If the number is too low, the - * simulation will not be safe. Must be - * non-negative. - * @param[in] maxNeighbors The default maximum number of other agents a new - * agent takes into account in the navigation. The - * larger this number, the longer the running time - * of the simulation. If the number is too low, the - * simulation will not be safe. - * @param[in] timeHorizon The default minimal amount of time for which a - * new agent's velocities that are computed by the - * simulation are safe with respect to other - * agents. The larger this number, the sooner an - * agent will respond to the presence of other - * agents, but the less freedom the agent has in - * choosing its velocities. Must be positive. - * @param[in] timeHorizonObst The default minimal amount of time for which a - * new agent's velocities that are computed by the - * simulation are safe with respect to obstacles. - * The larger this number, the sooner an agent will - * respond to the presence of obstacles, but the - * less freedom the agent has in choosing its - * velocities. Must be positive. - * @param[in] radius The default radius of a new agent. Must be - * non-negative. - * @param[in] maxSpeed The default maximum speed of a new agent. Must - * be non-negative. - */ - void setAgentDefaults(float neighborDist, std::size_t maxNeighbors, - float timeHorizon, float timeHorizonObst, float radius, - float maxSpeed); - - /** - * @brief Sets the default properties for any new agent that is added. - * @param[in] neighborDist The default maximum distance center-point to - * center-point to other agents a new agent takes - * into account in the navigation. The larger this - * number, the longer he running time of the - * simulation. If the number is too low, the - * simulation will not be safe. Must be - * non-negative. - * @param[in] maxNeighbors The default maximum number of other agents a new - * agent takes into account in the navigation. The - * larger this number, the longer the running time - * of the simulation. If the number is too low, the - * simulation will not be safe. - * @param[in] timeHorizon The default minimal amount of time for which a - * new agent's velocities that are computed by the - * simulation are safe with respect to other - * agents. The larger this number, the sooner an - * agent will respond to the presence of other - * agents, but the less freedom the agent has in - * choosing its velocities. Must be positive. - * @param[in] timeHorizonObst The default minimal amount of time for which a - * new agent's velocities that are computed by the - * simulation are safe with respect to obstacles. - * The larger this number, the sooner an agent will - * respond to the presence of obstacles, but the - * less freedom the agent has in choosing its - * velocities. Must be positive. - * @param[in] radius The default radius of a new agent. Must be - * non-negative. - * @param[in] maxSpeed The default maximum speed of a new agent. Must - * be non-negative. - * @param[in] velocity The default initial two-dimensional linear - * velocity of a new agent. - */ - void setAgentDefaults(float neighborDist, std::size_t maxNeighbors, - float timeHorizon, float timeHorizonObst, float radius, - float maxSpeed, const Vector2 &velocity); - - /** - * @brief Sets the maximum neighbor count of a specified agent. - * @param[in] agentNo The number of the agent whose maximum neighbor - * count is to be modified. - * @param[in] maxNeighbors The replacement maximum neighbor count. - */ - void setAgentMaxNeighbors(std::size_t agentNo, std::size_t maxNeighbors); - - /** - * @brief Sets the maximum speed of a specified agent. - * @param[in] agentNo The number of the agent whose maximum speed is to be - * modified. - * @param[in] maxSpeed The replacement maximum speed. Must be non-negative. - */ - void setAgentMaxSpeed(std::size_t agentNo, float maxSpeed); - - /** - * @brief Sets the maximum neighbor distance of a specified agent. - * @param[in] agentNo The number of the agent whose maximum neighbor - * distance is to be modified. - * @param[in] neighborDist The replacement maximum neighbor distance. Must be - * non-negative. - */ - void setAgentNeighborDist(std::size_t agentNo, float neighborDist); - - /** - * @brief Sets the two-dimensional position of a specified agent. - * @param[in] agentNo The number of the agent whose two-dimensional position - * is to be modified. - * @param[in] position The replacement of the two-dimensional position. - */ - void setAgentPosition(std::size_t agentNo, const Vector2 &position); - - /** - * @brief Sets the two-dimensional preferred velocity of a specified - * agent. - * @param[in] agentNo The number of the agent whose two-dimensional - * preferred velocity is to be modified. - * @param[in] prefVelocity The replacement of the two-dimensional preferred - * velocity. - */ - void setAgentPrefVelocity(std::size_t agentNo, const Vector2 &prefVelocity); - - /** - * @brief Sets the radius of a specified agent. - * @param[in] agentNo The number of the agent whose radius is to be modified. - * @param[in] radius The replacement radius. Must be non-negative. - */ - void setAgentRadius(std::size_t agentNo, float radius); - - /** - * @brief Sets the time horizon of a specified agent with respect to other - * agents. - * @param[in] agentNo The number of the agent whose time horizon is to be - * modified. - * @param[in] timeHorizon The replacement time horizon with respect to other - * agents. Must be positive. - */ - void setAgentTimeHorizon(std::size_t agentNo, float timeHorizon); - - /** - * @brief Sets the time horizon of a specified agent with respect to - * obstacles. - * @param[in] agentNo The number of the agent whose time horizon with - * respect to obstacles is to be modified. - * @param[in] timeHorizonObst The replacement time horizon with respect to - * obstacles. Must be positive. - */ - void setAgentTimeHorizonObst(std::size_t agentNo, float timeHorizonObst); - - /** - * @brief Sets the two-dimensional linear velocity of a specified agent. - * @param[in] agentNo The number of the agent whose two-dimensional linear - * velocity is to be modified. - * @param[in] velocity The replacement two-dimensional linear velocity. - */ - void setAgentVelocity(std::size_t agentNo, const Vector2 &velocity); - - /** - * @brief Sets the time step of the simulation. - * @param[in] timeStep The time step of the simulation. Must be positive. - */ - void setTimeStep(float timeStep) { timeStep_ = timeStep; } - - public: - /* Not implemented. */ - RVOSimulator2D(const RVOSimulator2D &other); - - /* Not implemented. */ - RVOSimulator2D &operator=(const RVOSimulator2D &other); - - std::vector<Agent2D *> agents_; - std::vector<Obstacle2D *> obstacles_; - Agent2D *defaultAgent_; - KdTree2D *kdTree_; - float globalTime_; - float timeStep_; - - friend class KdTree2D; -}; -} /* namespace RVO2D */ + /** + * \brief Error value. + * + * A value equal to the largest unsigned integer that is returned in case + * of an error by functions in RVO2D::RVOSimulator2D. + */ + const size_t RVO2D_ERROR = std::numeric_limits<size_t>::max(); + + /** + * \brief Defines a directed line. + */ + class Line { + public: + /** + * \brief A point on the directed line. + */ + Vector2 point; + + /** + * \brief The direction of the directed line. + */ + Vector2 direction; + }; + + class Agent2D; + class KdTree2D; + class Obstacle2D; + + /** + * \brief Defines the simulation. + * + * The main class of the library that contains all simulation functionality. + */ + class RVOSimulator2D { + public: + /** + * \brief Constructs a simulator instance. + */ + RVOSimulator2D(); + + /** + * \brief Constructs a simulator instance and sets the default + * properties for any new agent that is added. + * \param timeStep The time step of the simulation. + * Must be positive. + * \param neighborDist The default maximum distance (center point + * to center point) to other agents a new agent + * takes into account in the navigation. The + * larger this number, the longer he running + * time of the simulation. If the number is too + * low, the simulation will not be safe. Must be + * non-negative. + * \param maxNeighbors The default maximum number of other agents a + * new agent takes into account in the + * navigation. The larger this number, the + * longer the running time of the simulation. + * If the number is too low, the simulation + * will not be safe. + * \param timeHorizon The default minimal amount of time for which + * a new agent's velocities that are computed + * by the simulation are safe with respect to + * other agents. The larger this number, the + * sooner an agent will respond to the presence + * of other agents, but the less freedom the + * agent has in choosing its velocities. + * Must be positive. + * \param timeHorizonObst The default minimal amount of time for which + * a new agent's velocities that are computed + * by the simulation are safe with respect to + * obstacles. The larger this number, the + * sooner an agent will respond to the presence + * of obstacles, but the less freedom the agent + * has in choosing its velocities. + * Must be positive. + * \param radius The default radius of a new agent. + * Must be non-negative. + * \param maxSpeed The default maximum speed of a new agent. + * Must be non-negative. + * \param velocity The default initial two-dimensional linear + * velocity of a new agent (optional). + */ + RVOSimulator2D(float timeStep, float neighborDist, size_t maxNeighbors, + float timeHorizon, float timeHorizonObst, float radius, + float maxSpeed, const Vector2 &velocity = Vector2()); + + /** + * \brief Destroys this simulator instance. + */ + ~RVOSimulator2D(); + + /** + * \brief Adds a new agent with default properties to the + * simulation. + * \param position The two-dimensional starting position of + * this agent. + * \return The number of the agent, or RVO2D::RVO2D_ERROR when the agent + * defaults have not been set. + */ + size_t addAgent(const Vector2 &position); + + /** + * \brief Adds a new agent to the simulation. + * \param position The two-dimensional starting position of + * this agent. + * \param neighborDist The maximum distance (center point to + * center point) to other agents this agent + * takes into account in the navigation. The + * larger this number, the longer the running + * time of the simulation. If the number is too + * low, the simulation will not be safe. + * Must be non-negative. + * \param maxNeighbors The maximum number of other agents this + * agent takes into account in the navigation. + * The larger this number, the longer the + * running time of the simulation. If the + * number is too low, the simulation will not + * be safe. + * \param timeHorizon The minimal amount of time for which this + * agent's velocities that are computed by the + * simulation are safe with respect to other + * agents. The larger this number, the sooner + * this agent will respond to the presence of + * other agents, but the less freedom this + * agent has in choosing its velocities. + * Must be positive. + * \param timeHorizonObst The minimal amount of time for which this + * agent's velocities that are computed by the + * simulation are safe with respect to + * obstacles. The larger this number, the + * sooner this agent will respond to the + * presence of obstacles, but the less freedom + * this agent has in choosing its velocities. + * Must be positive. + * \param radius The radius of this agent. + * Must be non-negative. + * \param maxSpeed The maximum speed of this agent. + * Must be non-negative. + * \param velocity The initial two-dimensional linear velocity + * of this agent (optional). + * \return The number of the agent. + */ + size_t addAgent(const Vector2 &position, float neighborDist, + size_t maxNeighbors, float timeHorizon, + float timeHorizonObst, float radius, float maxSpeed, + const Vector2 &velocity = Vector2()); + + /** + * \brief Adds a new obstacle to the simulation. + * \param vertices List of the vertices of the polygonal + * obstacle in counterclockwise order. + * \return The number of the first vertex of the obstacle, + * or RVO2D::RVO2D_ERROR when the number of vertices is less than two. + * \note To add a "negative" obstacle, e.g. a bounding polygon around + * the environment, the vertices should be listed in clockwise + * order. + */ + size_t addObstacle(const std::vector<Vector2> &vertices); + + /** + * \brief Lets the simulator perform a simulation step and updates the + * two-dimensional position and two-dimensional velocity of + * each agent. + */ + void doStep(); + + /** + * \brief Returns the specified agent neighbor of the specified + * agent. + * \param agentNo The number of the agent whose agent + * neighbor is to be retrieved. + * \param neighborNo The number of the agent neighbor to be + * retrieved. + * \return The number of the neighboring agent. + */ + size_t getAgentAgentNeighbor(size_t agentNo, size_t neighborNo) const; + + /** + * \brief Returns the maximum neighbor count of a specified agent. + * \param agentNo The number of the agent whose maximum + * neighbor count is to be retrieved. + * \return The present maximum neighbor count of the agent. + */ + size_t getAgentMaxNeighbors(size_t agentNo) const; + + /** + * \brief Returns the maximum speed of a specified agent. + * \param agentNo The number of the agent whose maximum speed + * is to be retrieved. + * \return The present maximum speed of the agent. + */ + float getAgentMaxSpeed(size_t agentNo) const; + + /** + * \brief Returns the maximum neighbor distance of a specified + * agent. + * \param agentNo The number of the agent whose maximum + * neighbor distance is to be retrieved. + * \return The present maximum neighbor distance of the agent. + */ + float getAgentNeighborDist(size_t agentNo) const; + + /** + * \brief Returns the count of agent neighbors taken into account to + * compute the current velocity for the specified agent. + * \param agentNo The number of the agent whose count of agent + * neighbors is to be retrieved. + * \return The count of agent neighbors taken into account to compute + * the current velocity for the specified agent. + */ + size_t getAgentNumAgentNeighbors(size_t agentNo) const; + + /** + * \brief Returns the count of obstacle neighbors taken into account + * to compute the current velocity for the specified agent. + * \param agentNo The number of the agent whose count of + * obstacle neighbors is to be retrieved. + * \return The count of obstacle neighbors taken into account to + * compute the current velocity for the specified agent. + */ + size_t getAgentNumObstacleNeighbors(size_t agentNo) const; + + + /** + * \brief Returns the count of ORCA constraints used to compute + * the current velocity for the specified agent. + * \param agentNo The number of the agent whose count of ORCA + * constraints is to be retrieved. + * \return The count of ORCA constraints used to compute the current + * velocity for the specified agent. + */ + size_t getAgentNumORCALines(size_t agentNo) const; + + /** + * \brief Returns the specified obstacle neighbor of the specified + * agent. + * \param agentNo The number of the agent whose obstacle + * neighbor is to be retrieved. + * \param neighborNo The number of the obstacle neighbor to be + * retrieved. + * \return The number of the first vertex of the neighboring obstacle + * edge. + */ + size_t getAgentObstacleNeighbor(size_t agentNo, size_t neighborNo) const; + + /** + * \brief Returns the specified ORCA constraint of the specified + * agent. + * \param agentNo The number of the agent whose ORCA + * constraint is to be retrieved. + * \param lineNo The number of the ORCA constraint to be + * retrieved. + * \return A line representing the specified ORCA constraint. + * \note The halfplane to the left of the line is the region of + * permissible velocities with respect to the specified + * ORCA constraint. + */ + const Line &getAgentORCALine(size_t agentNo, size_t lineNo) const; + + /** + * \brief Returns the two-dimensional position of a specified + * agent. + * \param agentNo The number of the agent whose + * two-dimensional position is to be retrieved. + * \return The present two-dimensional position of the (center of the) + * agent. + */ + const Vector2 &getAgentPosition(size_t agentNo) const; + + /** + * \brief Returns the two-dimensional preferred velocity of a + * specified agent. + * \param agentNo The number of the agent whose + * two-dimensional preferred velocity is to be + * retrieved. + * \return The present two-dimensional preferred velocity of the agent. + */ + const Vector2 &getAgentPrefVelocity(size_t agentNo) const; + + /** + * \brief Returns the radius of a specified agent. + * \param agentNo The number of the agent whose radius is to + * be retrieved. + * \return The present radius of the agent. + */ + float getAgentRadius(size_t agentNo) const; + + /** + * \brief Returns the time horizon of a specified agent. + * \param agentNo The number of the agent whose time horizon + * is to be retrieved. + * \return The present time horizon of the agent. + */ + float getAgentTimeHorizon(size_t agentNo) const; + + /** + * \brief Returns the time horizon with respect to obstacles of a + * specified agent. + * \param agentNo The number of the agent whose time horizon + * with respect to obstacles is to be + * retrieved. + * \return The present time horizon with respect to obstacles of the + * agent. + */ + float getAgentTimeHorizonObst(size_t agentNo) const; + + /** + * \brief Returns the two-dimensional linear velocity of a + * specified agent. + * \param agentNo The number of the agent whose + * two-dimensional linear velocity is to be + * retrieved. + * \return The present two-dimensional linear velocity of the agent. + */ + const Vector2 &getAgentVelocity(size_t agentNo) const; + + /** + * \brief Returns the global time of the simulation. + * \return The present global time of the simulation (zero initially). + */ + float getGlobalTime() const; + + /** + * \brief Returns the count of agents in the simulation. + * \return The count of agents in the simulation. + */ + size_t getNumAgents() const; + + /** + * \brief Returns the count of obstacle vertices in the simulation. + * \return The count of obstacle vertices in the simulation. + */ + size_t getNumObstacleVertices() const; + + /** + * \brief Returns the two-dimensional position of a specified obstacle + * vertex. + * \param vertexNo The number of the obstacle vertex to be + * retrieved. + * \return The two-dimensional position of the specified obstacle + * vertex. + */ + const Vector2 &getObstacleVertex(size_t vertexNo) const; + + /** + * \brief Returns the number of the obstacle vertex succeeding the + * specified obstacle vertex in its polygon. + * \param vertexNo The number of the obstacle vertex whose + * successor is to be retrieved. + * \return The number of the obstacle vertex succeeding the specified + * obstacle vertex in its polygon. + */ + size_t getNextObstacleVertexNo(size_t vertexNo) const; + + /** + * \brief Returns the number of the obstacle vertex preceding the + * specified obstacle vertex in its polygon. + * \param vertexNo The number of the obstacle vertex whose + * predecessor is to be retrieved. + * \return The number of the obstacle vertex preceding the specified + * obstacle vertex in its polygon. + */ + size_t getPrevObstacleVertexNo(size_t vertexNo) const; + + /** + * \brief Returns the time step of the simulation. + * \return The present time step of the simulation. + */ + float getTimeStep() const; + + /** + * \brief Processes the obstacles that have been added so that they + * are accounted for in the simulation. + * \note Obstacles added to the simulation after this function has + * been called are not accounted for in the simulation. + */ + void processObstacles(); + + /** + * \brief Performs a visibility query between the two specified + * points with respect to the obstacles + * \param point1 The first point of the query. + * \param point2 The second point of the query. + * \param radius The minimal distance between the line + * connecting the two points and the obstacles + * in order for the points to be mutually + * visible (optional). Must be non-negative. + * \return A boolean specifying whether the two points are mutually + * visible. Returns true when the obstacles have not been + * processed. + */ + bool queryVisibility(const Vector2 &point1, const Vector2 &point2, + float radius = 0.0f) const; + + /** + * \brief Sets the default properties for any new agent that is + * added. + * \param neighborDist The default maximum distance (center point + * to center point) to other agents a new agent + * takes into account in the navigation. The + * larger this number, the longer he running + * time of the simulation. If the number is too + * low, the simulation will not be safe. + * Must be non-negative. + * \param maxNeighbors The default maximum number of other agents a + * new agent takes into account in the + * navigation. The larger this number, the + * longer the running time of the simulation. + * If the number is too low, the simulation + * will not be safe. + * \param timeHorizon The default minimal amount of time for which + * a new agent's velocities that are computed + * by the simulation are safe with respect to + * other agents. The larger this number, the + * sooner an agent will respond to the presence + * of other agents, but the less freedom the + * agent has in choosing its velocities. + * Must be positive. + * \param timeHorizonObst The default minimal amount of time for which + * a new agent's velocities that are computed + * by the simulation are safe with respect to + * obstacles. The larger this number, the + * sooner an agent will respond to the presence + * of obstacles, but the less freedom the agent + * has in choosing its velocities. + * Must be positive. + * \param radius The default radius of a new agent. + * Must be non-negative. + * \param maxSpeed The default maximum speed of a new agent. + * Must be non-negative. + * \param velocity The default initial two-dimensional linear + * velocity of a new agent (optional). + */ + void setAgentDefaults(float neighborDist, size_t maxNeighbors, + float timeHorizon, float timeHorizonObst, + float radius, float maxSpeed, + const Vector2 &velocity = Vector2()); + + /** + * \brief Sets the maximum neighbor count of a specified agent. + * \param agentNo The number of the agent whose maximum + * neighbor count is to be modified. + * \param maxNeighbors The replacement maximum neighbor count. + */ + void setAgentMaxNeighbors(size_t agentNo, size_t maxNeighbors); + + /** + * \brief Sets the maximum speed of a specified agent. + * \param agentNo The number of the agent whose maximum speed + * is to be modified. + * \param maxSpeed The replacement maximum speed. Must be + * non-negative. + */ + void setAgentMaxSpeed(size_t agentNo, float maxSpeed); + + /** + * \brief Sets the maximum neighbor distance of a specified agent. + * \param agentNo The number of the agent whose maximum + * neighbor distance is to be modified. + * \param neighborDist The replacement maximum neighbor distance. + * Must be non-negative. + */ + void setAgentNeighborDist(size_t agentNo, float neighborDist); + + /** + * \brief Sets the two-dimensional position of a specified agent. + * \param agentNo The number of the agent whose + * two-dimensional position is to be modified. + * \param position The replacement of the two-dimensional + * position. + */ + void setAgentPosition(size_t agentNo, const Vector2 &position); + + /** + * \brief Sets the two-dimensional preferred velocity of a + * specified agent. + * \param agentNo The number of the agent whose + * two-dimensional preferred velocity is to be + * modified. + * \param prefVelocity The replacement of the two-dimensional + * preferred velocity. + */ + void setAgentPrefVelocity(size_t agentNo, const Vector2 &prefVelocity); + + /** + * \brief Sets the radius of a specified agent. + * \param agentNo The number of the agent whose radius is to + * be modified. + * \param radius The replacement radius. + * Must be non-negative. + */ + void setAgentRadius(size_t agentNo, float radius); + + /** + * \brief Sets the time horizon of a specified agent with respect + * to other agents. + * \param agentNo The number of the agent whose time horizon + * is to be modified. + * \param timeHorizon The replacement time horizon with respect + * to other agents. Must be positive. + */ + void setAgentTimeHorizon(size_t agentNo, float timeHorizon); + + /** + * \brief Sets the time horizon of a specified agent with respect + * to obstacles. + * \param agentNo The number of the agent whose time horizon + * with respect to obstacles is to be modified. + * \param timeHorizonObst The replacement time horizon with respect to + * obstacles. Must be positive. + */ + void setAgentTimeHorizonObst(size_t agentNo, float timeHorizonObst); + + /** + * \brief Sets the two-dimensional linear velocity of a specified + * agent. + * \param agentNo The number of the agent whose + * two-dimensional linear velocity is to be + * modified. + * \param velocity The replacement two-dimensional linear + * velocity. + */ + void setAgentVelocity(size_t agentNo, const Vector2 &velocity); + + /** + * \brief Sets the time step of the simulation. + * \param timeStep The time step of the simulation. + * Must be positive. + */ + void setTimeStep(float timeStep); + + public: + std::vector<Agent2D *> agents_; + Agent2D *defaultAgent_; + float globalTime_; + KdTree2D *kdTree_; + std::vector<Obstacle2D *> obstacles_; + float timeStep_; + + friend class Agent2D; + friend class KdTree2D; + friend class Obstacle2D; + }; +} #endif /* RVO2D_RVO_SIMULATOR_H_ */ diff --git a/thirdparty/rvo2/rvo2_2d/Vector2.cc b/thirdparty/rvo2/rvo2_2d/Vector2.cc deleted file mode 100644 index 303e4c8fdd..0000000000 --- a/thirdparty/rvo2/rvo2_2d/Vector2.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Vector2.cpp - * RVO2 Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -/** - * @file Vector2.cc - * @brief Defines the Vector2 class. - */ - -#include "Vector2.h" - -#include <cmath> -#include <ostream> - -namespace RVO2D { -const float RVO2D_EPSILON = 0.00001F; - -Vector2::Vector2() : x_(0.0F), y_(0.0F) {} - -Vector2::Vector2(float x, float y) : x_(x), y_(y) {} - -Vector2 Vector2::operator-() const { return Vector2(-x_, -y_); } - -float Vector2::operator*(const Vector2 &vector) const { - return x_ * vector.x_ + y_ * vector.y_; -} - -Vector2 Vector2::operator*(float scalar) const { - return Vector2(x_ * scalar, y_ * scalar); -} - -Vector2 Vector2::operator/(float scalar) const { - const float invScalar = 1.0F / scalar; - - return Vector2(x_ * invScalar, y_ * invScalar); -} - -Vector2 Vector2::operator+(const Vector2 &vector) const { - return Vector2(x_ + vector.x_, y_ + vector.y_); -} - -Vector2 Vector2::operator-(const Vector2 &vector) const { - return Vector2(x_ - vector.x_, y_ - vector.y_); -} - -bool Vector2::operator==(const Vector2 &vector) const { - return x_ == vector.x_ && y_ == vector.y_; -} - -bool Vector2::operator!=(const Vector2 &vector) const { - return x_ != vector.x_ || y_ != vector.y_; -} - -Vector2 &Vector2::operator*=(float scalar) { - x_ *= scalar; - y_ *= scalar; - - return *this; -} - -Vector2 &Vector2::operator/=(float scalar) { - const float invScalar = 1.0F / scalar; - x_ *= invScalar; - y_ *= invScalar; - - return *this; -} - -Vector2 &Vector2::operator+=(const Vector2 &vector) { - x_ += vector.x_; - y_ += vector.y_; - - return *this; -} - -Vector2 &Vector2::operator-=(const Vector2 &vector) { - x_ -= vector.x_; - y_ -= vector.y_; - - return *this; -} - -Vector2 operator*(float scalar, const Vector2 &vector) { - return Vector2(scalar * vector.x(), scalar * vector.y()); -} - -std::ostream &operator<<(std::ostream &stream, const Vector2 &vector) { - stream << "(" << vector.x() << "," << vector.y() << ")"; - - return stream; -} - -float abs(const Vector2 &vector) { return std::sqrt(vector * vector); } - -float absSq(const Vector2 &vector) { return vector * vector; } - -float det(const Vector2 &vector1, const Vector2 &vector2) { - return vector1.x() * vector2.y() - vector1.y() * vector2.x(); -} - -float leftOf(const Vector2 &vector1, const Vector2 &vector2, - const Vector2 &vector3) { - return det(vector1 - vector3, vector2 - vector1); -} - -Vector2 normalize(const Vector2 &vector) { return vector / abs(vector); } -} /* namespace RVO */ diff --git a/thirdparty/rvo2/rvo2_2d/Vector2.h b/thirdparty/rvo2/rvo2_2d/Vector2.h index 0cc76f2ba1..24353e09f3 100644 --- a/thirdparty/rvo2/rvo2_2d/Vector2.h +++ b/thirdparty/rvo2/rvo2_2d/Vector2.h @@ -2,14 +2,13 @@ * Vector2.h * RVO2 Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,246 +27,320 @@ * Chapel Hill, N.C. 27599-3175 * United States of America * - * <https://gamma.cs.unc.edu/RVO2/> + * <http://gamma.cs.unc.edu/RVO2/> */ #ifndef RVO_VECTOR2_H_ #define RVO_VECTOR2_H_ /** - * @file Vector2.h - * @brief Declares and defines the Vector2 class. + * \file Vector2.h + * \brief Contains the Vector2 class. */ -#include <iosfwd> +#include <cmath> +#include <ostream> namespace RVO2D { -/** - * @brief A sufficiently small positive number. - */ -extern const float RVO2D_EPSILON; + /** + * \brief Defines a two-dimensional vector. + */ + class Vector2 { + public: + /** + * \brief Constructs and initializes a two-dimensional vector instance + * to (0.0, 0.0). + */ + inline Vector2() : x_(0.0f), y_(0.0f) { } -/** - * @brief Defines a two-dimensional vector. - */ -class Vector2 { - public: - /** - * @brief Constructs and initializes a two-dimensional vector instance to - * (0.0, 0.0). - */ - Vector2(); - - /** - * @brief Constructs and initializes a two-dimensional vector from the - * specified xy-coordinates. - * @param[in] x The x-coordinate of the two-dimensional vector. - * @param[in] y The y-coordinate of the two-dimensional vector. - */ - Vector2(float x, float y); - - /** - * @brief Returns the x-coordinate of this two-dimensional vector. - * @return The x-coordinate of the two-dimensional vector. - */ - float x() const { return x_; } - - /** - * @brief Returns the y-coordinate of this two-dimensional vector. - * @return The y-coordinate of the two-dimensional vector. - */ - float y() const { return y_; } - - /** - * @brief Computes the negation of this two-dimensional vector. - * @return The negation of this two-dimensional vector. - */ - Vector2 operator-() const; - - /** - * @brief Computes the dot product of this two-dimensional vector with the - * specified two-dimensional vector. - * @param[in] vector The two-dimensional vector with which the dot product - * should be computed. - * @return The dot product of this two-dimensional vector with a specified - * two-dimensional vector. - */ - float operator*(const Vector2 &vector) const; - - /** - * @brief Computes the scalar multiplication of this two-dimensional - * vector with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar multiplication - * should be computed. - * @return The scalar multiplication of this two-dimensional vector with a - * specified scalar value. - */ - Vector2 operator*(float scalar) const; - - /** - * @brief Computes the scalar division of this two-dimensional vector with - * the specified scalar value. - * @param[in] scalar The scalar value with which the scalar division should be - * computed. - * @return The scalar division of this two-dimensional vector with a - * specified scalar value. - */ - Vector2 operator/(float scalar) const; - - /** - * @brief Computes the vector sum of this two-dimensional vector with the - * specified two-dimensional vector. - * @param[in] vector The two-dimensional vector with which the vector sum - * should be computed. - * @return The vector sum of this two-dimensional vector with a specified - * two-dimensional vector. - */ - Vector2 operator+(const Vector2 &vector) const; - - /** - * @brief Computes the vector difference of this two-dimensional vector - * with the specified two-dimensional vector. - * @param[in] vector The two-dimensional vector with which the vector - * difference should be computed. - * @return The vector difference of this two-dimensional vector with a - * specified two-dimensional vector. - */ - Vector2 operator-(const Vector2 &vector) const; - - /** - * @brief Tests this two-dimensional vector for equality with the - * specified two-dimensional vector. - * @param[in] vector The two-dimensional vector with which to test for - * equality. - * @return True if the two-dimensional vectors are equal. - */ - bool operator==(const Vector2 &vector) const; - - /** - * @brief Tests this two-dimensional vector for inequality with the - * specified two-dimensional vector. - * @param[in] vector The two-dimensional vector with which to test for - * inequality. - * @return True if the two-dimensional vectors are not equal. - */ - bool operator!=(const Vector2 &vector) const; - - /** - * @brief Sets the value of this two-dimensional vector to the scalar - * multiplication of itself with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar multiplication - * should be computed. - * @return A reference to this two-dimensional vector. - */ - Vector2 &operator*=(float scalar); - - /** - * @brief Sets the value of this two-dimensional vector to the scalar - * division of itself with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar division should be - * computed. - * @return A reference to this two-dimensional vector. - */ - Vector2 &operator/=(float scalar); - - /** - * @brief Sets the value of this two-dimensional vector to the vector sum - * of itself with the specified two-dimensional vector. - * @param[in] vector The two-dimensional vector with which the vector sum - * should be computed. - * @return A reference to this two-dimensional vector. - */ - Vector2 &operator+=(const Vector2 &vector); - - /** - * @brief Sets the value of this two-dimensional vector to the vector - * difference of itself with the specified two-dimensional vector. - * @param[in] vector The two-dimensional vector with which the vector - * difference should be computed. - * @return A reference to this two-dimensional vector. - */ - Vector2 &operator-=(const Vector2 &vector); - - private: - float x_; - float y_; -}; + /** + * \brief Constructs and initializes a two-dimensional vector from + * the specified xy-coordinates. + * \param x The x-coordinate of the two-dimensional + * vector. + * \param y The y-coordinate of the two-dimensional + * vector. + */ + inline Vector2(float x, float y) : x_(x), y_(y) { } -/** - * @relates Vector2 - * @brief Computes the scalar multiplication of the specified - * two-dimensional vector with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar multiplication - * should be computed. - * @param[in] vector The two-dimensional vector with which the scalar - * multiplication should be computed. - * @return The scalar multiplication of the two-dimensional vector with the - * scalar value. - */ - Vector2 operator*(float scalar, const Vector2 &vector); + inline Vector2(const Vector2 &vector) + { + x_ = vector.x(); + y_ = vector.y(); + } -/** - * @relates Vector2 - * @brief Inserts the specified two-dimensional vector into the - * specified output stream. - * @param[in, out] stream The output stream into which the two-dimensional - * vector should be inserted. - * @param[in] vector The two-dimensional vector which to insert into the - * output stream. - * @return A reference to the output stream. - */ - std::ostream &operator<<(std::ostream &stream, - const Vector2 &vector); + /** + * \brief Returns the x-coordinate of this two-dimensional vector. + * \return The x-coordinate of the two-dimensional vector. + */ + inline float x() const { return x_; } -/** - * @relates Vector2 - * @brief Computes the length of a specified two-dimensional vector. - * @param[in] vector The two-dimensional vector whose length is to be computed. - * @return The length of the two-dimensional vector. - */ - float abs(const Vector2 &vector); + /** + * \brief Returns the y-coordinate of this two-dimensional vector. + * \return The y-coordinate of the two-dimensional vector. + */ + inline float y() const { return y_; } -/** - * @relates Vector2 - * @brief Computes the squared length of a specified two-dimensional vector. - * @param[in] vector The two-dimensional vector whose squared length is to be - * computed. - * @return The squared length of the two-dimensional vector. - */ - float absSq(const Vector2 &vector); + /** + * \brief Computes the negation of this two-dimensional vector. + * \return The negation of this two-dimensional vector. + */ + inline Vector2 operator-() const + { + return Vector2(-x_, -y_); + } -/** - * @relates Vector2 - * @brief Computes the determinant of a two-dimensional square matrix with - * rows consisting of the specified two-dimensional vectors. - * @param[in] vector1 The top row of the two-dimensional square matrix. - * @param[in] vector2 The bottom row of the two-dimensional square matrix. - * @return The determinant of the two-dimensional square matrix. - */ - float det(const Vector2 &vector1, const Vector2 &vector2); + /** + * \brief Computes the dot product of this two-dimensional vector with + * the specified two-dimensional vector. + * \param vector The two-dimensional vector with which the + * dot product should be computed. + * \return The dot product of this two-dimensional vector with a + * specified two-dimensional vector. + */ + inline float operator*(const Vector2 &vector) const + { + return x_ * vector.x() + y_ * vector.y(); + } -/** - * @brief Computes the signed distance from a line connecting th specified - * points to a specified point. - * @param[in] vector1 The first point on the line. - * @param[in] vector2 The second point on the line. - * @param[in] vector3 The point to which the signed distance is to be - * calculated. - * @return Positive when the point vector3 lies to the left of the line - * vector1-vector2. - */ - float leftOf(const Vector2 &vector1, const Vector2 &vector2, - const Vector2 &vector3); + /** + * \brief Computes the scalar multiplication of this + * two-dimensional vector with the specified scalar value. + * \param s The scalar value with which the scalar + * multiplication should be computed. + * \return The scalar multiplication of this two-dimensional vector + * with a specified scalar value. + */ + inline Vector2 operator*(float s) const + { + return Vector2(x_ * s, y_ * s); + } -/** - * @relates Vector2 - * @brief Computes the normalization of the specified two-dimensional - * vector. - * @param[in] vector The two-dimensional vector whose normalization is to be - * computed. - * @return The normalization of the two-dimensional vector. - */ - Vector2 normalize(const Vector2 &vector); -} /* namespace RVO2D */ + /** + * \brief Computes the scalar division of this two-dimensional vector + * with the specified scalar value. + * \param s The scalar value with which the scalar + * division should be computed. + * \return The scalar division of this two-dimensional vector with a + * specified scalar value. + */ + inline Vector2 operator/(float s) const + { + const float invS = 1.0f / s; + + return Vector2(x_ * invS, y_ * invS); + } + + /** + * \brief Computes the vector sum of this two-dimensional vector with + * the specified two-dimensional vector. + * \param vector The two-dimensional vector with which the + * vector sum should be computed. + * \return The vector sum of this two-dimensional vector with a + * specified two-dimensional vector. + */ + inline Vector2 operator+(const Vector2 &vector) const + { + return Vector2(x_ + vector.x(), y_ + vector.y()); + } + + /** + * \brief Computes the vector difference of this two-dimensional + * vector with the specified two-dimensional vector. + * \param vector The two-dimensional vector with which the + * vector difference should be computed. + * \return The vector difference of this two-dimensional vector with a + * specified two-dimensional vector. + */ + inline Vector2 operator-(const Vector2 &vector) const + { + return Vector2(x_ - vector.x(), y_ - vector.y()); + } + + /** + * \brief Tests this two-dimensional vector for equality with the + * specified two-dimensional vector. + * \param vector The two-dimensional vector with which to + * test for equality. + * \return True if the two-dimensional vectors are equal. + */ + inline bool operator==(const Vector2 &vector) const + { + return x_ == vector.x() && y_ == vector.y(); + } + + /** + * \brief Tests this two-dimensional vector for inequality with the + * specified two-dimensional vector. + * \param vector The two-dimensional vector with which to + * test for inequality. + * \return True if the two-dimensional vectors are not equal. + */ + inline bool operator!=(const Vector2 &vector) const + { + return x_ != vector.x() || y_ != vector.y(); + } + + /** + * \brief Sets the value of this two-dimensional vector to the scalar + * multiplication of itself with the specified scalar value. + * \param s The scalar value with which the scalar + * multiplication should be computed. + * \return A reference to this two-dimensional vector. + */ + inline Vector2 &operator*=(float s) + { + x_ *= s; + y_ *= s; + + return *this; + } + + /** + * \brief Sets the value of this two-dimensional vector to the scalar + * division of itself with the specified scalar value. + * \param s The scalar value with which the scalar + * division should be computed. + * \return A reference to this two-dimensional vector. + */ + inline Vector2 &operator/=(float s) + { + const float invS = 1.0f / s; + x_ *= invS; + y_ *= invS; + + return *this; + } + + /** + * \brief Sets the value of this two-dimensional vector to the vector + * sum of itself with the specified two-dimensional vector. + * \param vector The two-dimensional vector with which the + * vector sum should be computed. + * \return A reference to this two-dimensional vector. + */ + inline Vector2 &operator+=(const Vector2 &vector) + { + x_ += vector.x(); + y_ += vector.y(); + + return *this; + } + + /** + * \brief Sets the value of this two-dimensional vector to the vector + * difference of itself with the specified two-dimensional + * vector. + * \param vector The two-dimensional vector with which the + * vector difference should be computed. + * \return A reference to this two-dimensional vector. + */ + inline Vector2 &operator-=(const Vector2 &vector) + { + x_ -= vector.x(); + y_ -= vector.y(); + + return *this; + } + + inline Vector2 &operator=(const Vector2 &vector) + { + x_ = vector.x(); + y_ = vector.y(); + + return *this; + } + + private: + float x_; + float y_; + }; + + /** + * \relates Vector2 + * \brief Computes the scalar multiplication of the specified + * two-dimensional vector with the specified scalar value. + * \param s The scalar value with which the scalar + * multiplication should be computed. + * \param vector The two-dimensional vector with which the scalar + * multiplication should be computed. + * \return The scalar multiplication of the two-dimensional vector with the + * scalar value. + */ + inline Vector2 operator*(float s, const Vector2 &vector) + { + return Vector2(s * vector.x(), s * vector.y()); + } + + /** + * \relates Vector2 + * \brief Inserts the specified two-dimensional vector into the specified + * output stream. + * \param os The output stream into which the two-dimensional + * vector should be inserted. + * \param vector The two-dimensional vector which to insert into + * the output stream. + * \return A reference to the output stream. + */ + inline std::ostream &operator<<(std::ostream &os, const Vector2 &vector) + { + os << "(" << vector.x() << "," << vector.y() << ")"; + + return os; + } + + /** + * \relates Vector2 + * \brief Computes the length of a specified two-dimensional vector. + * \param vector The two-dimensional vector whose length is to be + * computed. + * \return The length of the two-dimensional vector. + */ + inline float abs(const Vector2 &vector) + { + return std::sqrt(vector * vector); + } + + /** + * \relates Vector2 + * \brief Computes the squared length of a specified two-dimensional + * vector. + * \param vector The two-dimensional vector whose squared length + * is to be computed. + * \return The squared length of the two-dimensional vector. + */ + inline float absSq(const Vector2 &vector) + { + return vector * vector; + } + + /** + * \relates Vector2 + * \brief Computes the determinant of a two-dimensional square matrix with + * rows consisting of the specified two-dimensional vectors. + * \param vector1 The top row of the two-dimensional square + * matrix. + * \param vector2 The bottom row of the two-dimensional square + * matrix. + * \return The determinant of the two-dimensional square matrix. + */ + inline float det(const Vector2 &vector1, const Vector2 &vector2) + { + return vector1.x() * vector2.y() - vector1.y() * vector2.x(); + } + + /** + * \relates Vector2 + * \brief Computes the normalization of the specified two-dimensional + * vector. + * \param vector The two-dimensional vector whose normalization + * is to be computed. + * \return The normalization of the two-dimensional vector. + */ + inline Vector2 normalize(const Vector2 &vector) + { + return vector / abs(vector); + } +} #endif /* RVO_VECTOR2_H_ */ diff --git a/thirdparty/rvo2/rvo2_3d/Agent3d.cc b/thirdparty/rvo2/rvo2_3d/Agent3d.cc deleted file mode 100644 index 860ebdc58c..0000000000 --- a/thirdparty/rvo2/rvo2_3d/Agent3d.cc +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Agent3d.cc - * RVO2-3D Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -#include "Agent3d.h" - -#include <algorithm> -#include <cmath> - -#include "KdTree3d.h" -#include "RVOSimulator3d.h" - -namespace RVO3D { -namespace { -/** - * @brief A sufficiently small positive number. - */ -const float RVO3D_EPSILON = 0.00001F; - -/** - * @brief Defines a directed line. - */ -class Line3D { - public: - /** - * @brief Constructs a directed line.`` - */ - Line3D(); - - /** - * @brief The direction of the directed line. - */ - Vector3 direction; - - /** - * @brief A point on the directed line. - */ - Vector3 point; -}; - -Line3D::Line3D() {} - -/** - * @brief Solves a one-dimensional linear program on a specified line - * subject to linear constraints defined by planes and a spherical - * constraint. - * @param[in] planes Planes defining the linear constraints. - * @param[in] planeNo The plane on which the line lies. - * @param[in] line The line on which the one-dimensional linear program - * is solved. - * @param[in] radius The radius of the spherical constraint. - * @param[in] optVelocity The optimization velocity. - * @param[in] directionOpt True if the direction should be optimized. - * @param[in] result A reference to the result of the linear program. - * @return True if successful. - */ -bool linearProgram1(const std::vector<Plane> &planes, std::size_t planeNo, - const Line3D &line, float radius, const Vector3 &optVelocity, - bool directionOpt, - Vector3 &result) { /* NOLINT(runtime/references) */ - const float dotProduct = line.point * line.direction; - const float discriminant = - dotProduct * dotProduct + radius * radius - absSq(line.point); - - if (discriminant < 0.0F) { - /* Max speed sphere fully invalidates line. */ - return false; - } - - const float sqrtDiscriminant = std::sqrt(discriminant); - float tLeft = -dotProduct - sqrtDiscriminant; - float tRight = -dotProduct + sqrtDiscriminant; - - for (std::size_t i = 0U; i < planeNo; ++i) { - const float numerator = (planes[i].point - line.point) * planes[i].normal; - const float denominator = line.direction * planes[i].normal; - - if (denominator * denominator <= RVO3D_EPSILON) { - /* Lines line is (almost) parallel to plane i. */ - if (numerator > 0.0F) { - return false; - } - - continue; - } - - const float t = numerator / denominator; - - if (denominator >= 0.0F) { - /* Plane i bounds line on the left. */ - tLeft = std::max(tLeft, t); - } else { - /* Plane i bounds line on the right. */ - tRight = std::min(tRight, t); - } - - if (tLeft > tRight) { - return false; - } - } - - if (directionOpt) { - /* Optimize direction. */ - if (optVelocity * line.direction > 0.0F) { - /* Take right extreme. */ - result = line.point + tRight * line.direction; - } else { - /* Take left extreme. */ - result = line.point + tLeft * line.direction; - } - } else { - /* Optimize closest point. */ - const float t = line.direction * (optVelocity - line.point); - - if (t < tLeft) { - result = line.point + tLeft * line.direction; - } else if (t > tRight) { - result = line.point + tRight * line.direction; - } else { - result = line.point + t * line.direction; - } - } - - return true; -} - -/** - * @brief Solves a two-dimensional linear program on a specified plane - * subject to linear constraints defined by planes and a spherical - * constraint. - * @param[in] planes Planes defining the linear constraints. - * @param[in] planeNo The plane on which the two-dimensional linear - * program is solved. - * @param[in] radius The radius of the spherical constraint. - * @param[in] optVelocity The optimization velocity. - * @param[in] directionOpt True if the direction should be optimized. - * @param[out] result A reference to the result of the linear program. - * @return True if successful. - */ -bool linearProgram2(const std::vector<Plane> &planes, std::size_t planeNo, - float radius, const Vector3 &optVelocity, bool directionOpt, - Vector3 &result) { /* NOLINT(runtime/references) */ - const float planeDist = planes[planeNo].point * planes[planeNo].normal; - const float planeDistSq = planeDist * planeDist; - const float radiusSq = radius * radius; - - if (planeDistSq > radiusSq) { - /* Max speed sphere fully invalidates plane planeNo. */ - return false; - } - - const float planeRadiusSq = radiusSq - planeDistSq; - - const Vector3 planeCenter = planeDist * planes[planeNo].normal; - - if (directionOpt) { - /* Project direction optVelocity on plane planeNo. */ - const Vector3 planeOptVelocity = - optVelocity - - (optVelocity * planes[planeNo].normal) * planes[planeNo].normal; - const float planeOptVelocityLengthSq = absSq(planeOptVelocity); - - if (planeOptVelocityLengthSq <= RVO3D_EPSILON) { - result = planeCenter; - } else { - result = - planeCenter + std::sqrt(planeRadiusSq / planeOptVelocityLengthSq) * - planeOptVelocity; - } - } else { - /* Project point optVelocity on plane planeNo. */ - result = optVelocity + - ((planes[planeNo].point - optVelocity) * planes[planeNo].normal) * - planes[planeNo].normal; - - /* If outside planeCircle, project on planeCircle. */ - if (absSq(result) > radiusSq) { - const Vector3 planeResult = result - planeCenter; - const float planeResultLengthSq = absSq(planeResult); - result = planeCenter + - std::sqrt(planeRadiusSq / planeResultLengthSq) * planeResult; - } - } - - for (std::size_t i = 0U; i < planeNo; ++i) { - if (planes[i].normal * (planes[i].point - result) > 0.0F) { - /* Result does not satisfy constraint i. Compute new optimal result. - * Compute intersection line of plane i and plane planeNo. - */ - Vector3 crossProduct = cross(planes[i].normal, planes[planeNo].normal); - - if (absSq(crossProduct) <= RVO3D_EPSILON) { - /* Planes planeNo and i are (almost) parallel, and plane i fully - * invalidates plane planeNo. - */ - return false; - } - - Line3D line; - line.direction = normalize(crossProduct); - const Vector3 lineNormal = cross(line.direction, planes[planeNo].normal); - line.point = - planes[planeNo].point + - (((planes[i].point - planes[planeNo].point) * planes[i].normal) / - (lineNormal * planes[i].normal)) * - lineNormal; - - if (!linearProgram1(planes, i, line, radius, optVelocity, directionOpt, - result)) { - return false; - } - } - } - - return true; -} - -/** - * @brief Solves a three-dimensional linear program subject to linear - * constraints defined by planes and a spherical constraint. - * @param[in] planes Planes defining the linear constraints. - * @param[in] radius The radius of the spherical constraint. - * @param[in] optVelocity The optimization velocity. - * @param[in] directionOpt True if the direction should be optimized. - * @param[out] result A reference to the result of the linear program. - * @return The number of the plane it fails on, and the number of planes if - * successful. - */ -std::size_t linearProgram3(const std::vector<Plane> &planes, float radius, - const Vector3 &optVelocity, bool directionOpt, - Vector3 &result) { /* NOLINT(runtime/references) */ - if (directionOpt) { - /* Optimize direction. Note that the optimization velocity is of unit length - * in this case. - */ - result = optVelocity * radius; - } else if (absSq(optVelocity) > radius * radius) { - /* Optimize closest point and outside circle. */ - result = normalize(optVelocity) * radius; - } else { - /* Optimize closest point and inside circle. */ - result = optVelocity; - } - - for (std::size_t i = 0U; i < planes.size(); ++i) { - if (planes[i].normal * (planes[i].point - result) > 0.0F) { - /* Result does not satisfy constraint i. Compute new optimal result. */ - const Vector3 tempResult = result; - - if (!linearProgram2(planes, i, radius, optVelocity, directionOpt, - result)) { - result = tempResult; - return i; - } - } - } - - return planes.size(); -} - -/** - * @brief Solves a four-dimensional linear program subject to linear - * constraints defined by planes and a spherical constraint. - * @param[in] planes Planes defining the linear constraints. - * @param[in] beginPlane The plane on which the three-dimensional linear - * program failed. - * @param[in] radius The radius of the spherical constraint. - * @param[out] result A reference to the result of the linear program. - */ -void linearProgram4(const std::vector<Plane> &planes, std::size_t beginPlane, - float radius, - Vector3 &result) { /* NOLINT(runtime/references) */ - float distance = 0.0F; - - for (std::size_t i = beginPlane; i < planes.size(); ++i) { - if (planes[i].normal * (planes[i].point - result) > distance) { - /* Result does not satisfy constraint of plane i. */ - std::vector<Plane> projPlanes; - - for (std::size_t j = 0U; j < i; ++j) { - Plane plane; - - const Vector3 crossProduct = cross(planes[j].normal, planes[i].normal); - - if (absSq(crossProduct) <= RVO3D_EPSILON) { - /* Plane i and plane j are (almost) parallel. */ - if (planes[i].normal * planes[j].normal > 0.0F) { - /* Plane i and plane j point in the same direction. */ - continue; - } - - /* Plane i and plane j point in opposite direction. */ - plane.point = 0.5F * (planes[i].point + planes[j].point); - } else { - /* Plane.point is point on line of intersection between plane i and - * plane j. - */ - const Vector3 lineNormal = cross(crossProduct, planes[i].normal); - plane.point = - planes[i].point + - (((planes[j].point - planes[i].point) * planes[j].normal) / - (lineNormal * planes[j].normal)) * - lineNormal; - } - - plane.normal = normalize(planes[j].normal - planes[i].normal); - projPlanes.push_back(plane); - } - - const Vector3 tempResult = result; - - if (linearProgram3(projPlanes, radius, planes[i].normal, true, result) < - projPlanes.size()) { - /* This should in principle not happen. The result is by definition - * already in the feasible region of this linear program. If it fails, - * it is due to small floating point error, and the current result is - * kept. - */ - result = tempResult; - } - - distance = planes[i].normal * (planes[i].point - result); - } - } -} -} /* namespace */ - -Agent3D::Agent3D() - : id_(0U), - maxNeighbors_(0U), - maxSpeed_(0.0F), - neighborDist_(0.0F), - radius_(0.0F), - timeHorizon_(0.0F) {} - -Agent3D::~Agent3D() {} - -void Agent3D::computeNeighbors(RVOSimulator3D *sim_) { - agentNeighbors_.clear(); - - if (maxNeighbors_ > 0) { - sim_->kdTree_->computeAgentNeighbors(this, neighborDist_ * neighborDist_); - } -} - -void Agent3D::computeNewVelocity(RVOSimulator3D *sim_) { - orcaPlanes_.clear(); - const float invTimeHorizon = 1.0F / timeHorizon_; - - /* Create agent ORCA planes. */ - for (std::size_t i = 0U; i < agentNeighbors_.size(); ++i) { - const Agent3D *const other = agentNeighbors_[i].second; - const Vector3 relativePosition = other->position_ - position_; - const Vector3 relativeVelocity = velocity_ - other->velocity_; - const float distSq = absSq(relativePosition); - const float combinedRadius = radius_ + other->radius_; - const float combinedRadiusSq = combinedRadius * combinedRadius; - - Plane plane; - Vector3 u; - - if (distSq > combinedRadiusSq) { - /* No collision. */ - const Vector3 w = relativeVelocity - invTimeHorizon * relativePosition; - /* Vector from cutoff center to relative velocity. */ - const float wLengthSq = absSq(w); - - const float dotProduct = w * relativePosition; - - if (dotProduct < 0.0F && - dotProduct * dotProduct > combinedRadiusSq * wLengthSq) { - /* Project on cut-off circle. */ - const float wLength = std::sqrt(wLengthSq); - const Vector3 unitW = w / wLength; - - plane.normal = unitW; - u = (combinedRadius * invTimeHorizon - wLength) * unitW; - } else { - /* Project on cone. */ - const float a = distSq; - const float b = relativePosition * relativeVelocity; - const float c = absSq(relativeVelocity) - - absSq(cross(relativePosition, relativeVelocity)) / - (distSq - combinedRadiusSq); - const float t = (b + std::sqrt(b * b - a * c)) / a; - const Vector3 ww = relativeVelocity - t * relativePosition; - const float wwLength = abs(ww); - const Vector3 unitWW = ww / wwLength; - - plane.normal = unitWW; - u = (combinedRadius * t - wwLength) * unitWW; - } - } else { - /* Collision. */ - const float invTimeStep = 1.0F / sim_->timeStep_; - const Vector3 w = relativeVelocity - invTimeStep * relativePosition; - const float wLength = abs(w); - const Vector3 unitW = w / wLength; - - plane.normal = unitW; - u = (combinedRadius * invTimeStep - wLength) * unitW; - } - - plane.point = velocity_ + 0.5F * u; - orcaPlanes_.push_back(plane); - } - - const std::size_t planeFail = linearProgram3( - orcaPlanes_, maxSpeed_, prefVelocity_, false, newVelocity_); - - if (planeFail < orcaPlanes_.size()) { - linearProgram4(orcaPlanes_, planeFail, maxSpeed_, newVelocity_); - } -} - -void Agent3D::insertAgentNeighbor(const Agent3D *agent, float &rangeSq) { - if (this != agent) { - const float distSq = absSq(position_ - agent->position_); - - if (distSq < rangeSq) { - if (agentNeighbors_.size() < maxNeighbors_) { - agentNeighbors_.push_back(std::make_pair(distSq, agent)); - } - - std::size_t i = agentNeighbors_.size() - 1U; - - while (i != 0U && distSq < agentNeighbors_[i - 1U].first) { - agentNeighbors_[i] = agentNeighbors_[i - 1U]; - --i; - } - - agentNeighbors_[i] = std::make_pair(distSq, agent); - - if (agentNeighbors_.size() == maxNeighbors_) { - rangeSq = agentNeighbors_.back().first; - } - } - } -} - -void Agent3D::update(RVOSimulator3D *sim_) { - velocity_ = newVelocity_; - position_ += velocity_ * sim_->timeStep_; -} -} /* namespace RVO3D */ diff --git a/thirdparty/rvo2/rvo2_3d/Agent3d.cpp b/thirdparty/rvo2/rvo2_3d/Agent3d.cpp new file mode 100644 index 0000000000..bddf226db1 --- /dev/null +++ b/thirdparty/rvo2/rvo2_3d/Agent3d.cpp @@ -0,0 +1,449 @@ +/* + * Agent.cpp + * RVO2-3D Library + * + * Copyright 2008 University of North Carolina at Chapel Hill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Please send all bug reports to <geom@cs.unc.edu>. + * + * The authors may be contacted via: + * + * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha + * Dept. of Computer Science + * 201 S. Columbia St. + * Frederick P. Brooks, Jr. Computer Science Bldg. + * Chapel Hill, N.C. 27599-3175 + * United States of America + * + * <https://gamma.cs.unc.edu/RVO2/> + */ + +#include "Agent3d.h" + +#include <cmath> +#include <algorithm> + +#include "Definitions.h" +#include "KdTree3d.h" + +namespace RVO3D { + /** + * \brief A sufficiently small positive number. + */ + const float RVO3D_EPSILON = 0.00001f; + + /** + * \brief Defines a directed line. + */ + class Line3D { + public: + /** + * \brief The direction of the directed line. + */ + Vector3 direction; + + /** + * \brief A point on the directed line. + */ + Vector3 point; + }; + + /** + * \brief Solves a one-dimensional linear program on a specified line subject to linear constraints defined by planes and a spherical constraint. + * \param planes Planes defining the linear constraints. + * \param planeNo The plane on which the line lies. + * \param line The line on which the 1-d linear program is solved + * \param radius The radius of the spherical constraint. + * \param optVelocity The optimization velocity. + * \param directionOpt True if the direction should be optimized. + * \param result A reference to the result of the linear program. + * \return True if successful. + */ + bool linearProgram1(const std::vector<Plane> &planes, size_t planeNo, const Line3D &line, float radius, const Vector3 &optVelocity, bool directionOpt, Vector3 &result); + + /** + * \brief Solves a two-dimensional linear program on a specified plane subject to linear constraints defined by planes and a spherical constraint. + * \param planes Planes defining the linear constraints. + * \param planeNo The plane on which the 2-d linear program is solved + * \param radius The radius of the spherical constraint. + * \param optVelocity The optimization velocity. + * \param directionOpt True if the direction should be optimized. + * \param result A reference to the result of the linear program. + * \return True if successful. + */ + bool linearProgram2(const std::vector<Plane> &planes, size_t planeNo, float radius, const Vector3 &optVelocity, bool directionOpt, Vector3 &result); + + /** + * \brief Solves a three-dimensional linear program subject to linear constraints defined by planes and a spherical constraint. + * \param planes Planes defining the linear constraints. + * \param radius The radius of the spherical constraint. + * \param optVelocity The optimization velocity. + * \param directionOpt True if the direction should be optimized. + * \param result A reference to the result of the linear program. + * \return The number of the plane it fails on, and the number of planes if successful. + */ + size_t linearProgram3(const std::vector<Plane> &planes, float radius, const Vector3 &optVelocity, bool directionOpt, Vector3 &result); + + /** + * \brief Solves a four-dimensional linear program subject to linear constraints defined by planes and a spherical constraint. + * \param planes Planes defining the linear constraints. + * \param beginPlane The plane on which the 3-d linear program failed. + * \param radius The radius of the spherical constraint. + * \param result A reference to the result of the linear program. + */ + void linearProgram4(const std::vector<Plane> &planes, size_t beginPlane, float radius, Vector3 &result); + + Agent3D::Agent3D() : id_(0), maxNeighbors_(0), maxSpeed_(0.0f), neighborDist_(0.0f), radius_(0.0f), timeHorizon_(0.0f) { } + + void Agent3D::computeNeighbors(RVOSimulator3D *sim_) + { + agentNeighbors_.clear(); + + if (maxNeighbors_ > 0) { + sim_->kdTree_->computeAgentNeighbors(this, neighborDist_ * neighborDist_); + } + } + + void Agent3D::computeNewVelocity(RVOSimulator3D *sim_) + { + orcaPlanes_.clear(); + + const float invTimeHorizon = 1.0f / timeHorizon_; + + /* Create agent ORCA planes. */ + for (size_t i = 0; i < agentNeighbors_.size(); ++i) { + const Agent3D *const other = agentNeighbors_[i].second; + + //const float timeHorizon_mod = (avoidance_priority_ - other->avoidance_priority_ + 1.0f) * 0.5f; + //const float invTimeHorizon = (1.0f / timeHorizon_) * timeHorizon_mod; + + const Vector3 relativePosition = other->position_ - position_; + const Vector3 relativeVelocity = velocity_ - other->velocity_; + const float distSq = absSq(relativePosition); + const float combinedRadius = radius_ + other->radius_; + const float combinedRadiusSq = sqr(combinedRadius); + + Plane plane; + Vector3 u; + + if (distSq > combinedRadiusSq) { + /* No collision. */ + const Vector3 w = relativeVelocity - invTimeHorizon * relativePosition; + /* Vector from cutoff center to relative velocity. */ + const float wLengthSq = absSq(w); + + const float dotProduct = w * relativePosition; + + if (dotProduct < 0.0f && sqr(dotProduct) > combinedRadiusSq * wLengthSq) { + /* Project on cut-off circle. */ + const float wLength = std::sqrt(wLengthSq); + const Vector3 unitW = w / wLength; + + plane.normal = unitW; + u = (combinedRadius * invTimeHorizon - wLength) * unitW; + } + else { + /* Project on cone. */ + const float a = distSq; + const float b = relativePosition * relativeVelocity; + const float c = absSq(relativeVelocity) - absSq(cross(relativePosition, relativeVelocity)) / (distSq - combinedRadiusSq); + const float t = (b + std::sqrt(sqr(b) - a * c)) / a; + const Vector3 w = relativeVelocity - t * relativePosition; + const float wLength = abs(w); + const Vector3 unitW = w / wLength; + + plane.normal = unitW; + u = (combinedRadius * t - wLength) * unitW; + } + } + else { + /* Collision. */ + const float invTimeStep = 1.0f / sim_->timeStep_; + const Vector3 w = relativeVelocity - invTimeStep * relativePosition; + const float wLength = abs(w); + const Vector3 unitW = w / wLength; + + plane.normal = unitW; + u = (combinedRadius * invTimeStep - wLength) * unitW; + } + + plane.point = velocity_ + 0.5f * u; + orcaPlanes_.push_back(plane); + } + + const size_t planeFail = linearProgram3(orcaPlanes_, maxSpeed_, prefVelocity_, false, newVelocity_); + + if (planeFail < orcaPlanes_.size()) { + linearProgram4(orcaPlanes_, planeFail, maxSpeed_, newVelocity_); + } + } + + void Agent3D::insertAgentNeighbor(const Agent3D *agent, float &rangeSq) + { + // no point processing same agent + if (this == agent) { + return; + } + // ignore other agent if layers/mask bitmasks have no matching bit + if ((avoidance_mask_ & agent->avoidance_layers_) == 0) { + return; + } + + if (avoidance_priority_ > agent->avoidance_priority_) { + return; + } + + const float distSq = absSq(position_ - agent->position_); + + if (distSq < rangeSq) { + if (agentNeighbors_.size() < maxNeighbors_) { + agentNeighbors_.push_back(std::make_pair(distSq, agent)); + } + + size_t i = agentNeighbors_.size() - 1; + + while (i != 0 && distSq < agentNeighbors_[i - 1].first) { + agentNeighbors_[i] = agentNeighbors_[i - 1]; + --i; + } + + agentNeighbors_[i] = std::make_pair(distSq, agent); + + if (agentNeighbors_.size() == maxNeighbors_) { + rangeSq = agentNeighbors_.back().first; + } + } + } + + void Agent3D::update(RVOSimulator3D *sim_) + { + velocity_ = newVelocity_; + position_ += velocity_ * sim_->timeStep_; + } + + bool linearProgram1(const std::vector<Plane> &planes, size_t planeNo, const Line3D &line, float radius, const Vector3 &optVelocity, bool directionOpt, Vector3 &result) + { + const float dotProduct = line.point * line.direction; + const float discriminant = sqr(dotProduct) + sqr(radius) - absSq(line.point); + + if (discriminant < 0.0f) { + /* Max speed sphere fully invalidates line. */ + return false; + } + + const float sqrtDiscriminant = std::sqrt(discriminant); + float tLeft = -dotProduct - sqrtDiscriminant; + float tRight = -dotProduct + sqrtDiscriminant; + + for (size_t i = 0; i < planeNo; ++i) { + const float numerator = (planes[i].point - line.point) * planes[i].normal; + const float denominator = line.direction * planes[i].normal; + + if (sqr(denominator) <= RVO3D_EPSILON) { + /* Lines3D line is (almost) parallel to plane i. */ + if (numerator > 0.0f) { + return false; + } + else { + continue; + } + } + + const float t = numerator / denominator; + + if (denominator >= 0.0f) { + /* Plane i bounds line on the left. */ + tLeft = std::max(tLeft, t); + } + else { + /* Plane i bounds line on the right. */ + tRight = std::min(tRight, t); + } + + if (tLeft > tRight) { + return false; + } + } + + if (directionOpt) { + /* Optimize direction. */ + if (optVelocity * line.direction > 0.0f) { + /* Take right extreme. */ + result = line.point + tRight * line.direction; + } + else { + /* Take left extreme. */ + result = line.point + tLeft * line.direction; + } + } + else { + /* Optimize closest point. */ + const float t = line.direction * (optVelocity - line.point); + + if (t < tLeft) { + result = line.point + tLeft * line.direction; + } + else if (t > tRight) { + result = line.point + tRight * line.direction; + } + else { + result = line.point + t * line.direction; + } + } + + return true; + } + + bool linearProgram2(const std::vector<Plane> &planes, size_t planeNo, float radius, const Vector3 &optVelocity, bool directionOpt, Vector3 &result) + { + const float planeDist = planes[planeNo].point * planes[planeNo].normal; + const float planeDistSq = sqr(planeDist); + const float radiusSq = sqr(radius); + + if (planeDistSq > radiusSq) { + /* Max speed sphere fully invalidates plane planeNo. */ + return false; + } + + const float planeRadiusSq = radiusSq - planeDistSq; + + const Vector3 planeCenter = planeDist * planes[planeNo].normal; + + if (directionOpt) { + /* Project direction optVelocity on plane planeNo. */ + const Vector3 planeOptVelocity = optVelocity - (optVelocity * planes[planeNo].normal) * planes[planeNo].normal; + const float planeOptVelocityLengthSq = absSq(planeOptVelocity); + + if (planeOptVelocityLengthSq <= RVO3D_EPSILON) { + result = planeCenter; + } + else { + result = planeCenter + std::sqrt(planeRadiusSq / planeOptVelocityLengthSq) * planeOptVelocity; + } + } + else { + /* Project point optVelocity on plane planeNo. */ + result = optVelocity + ((planes[planeNo].point - optVelocity) * planes[planeNo].normal) * planes[planeNo].normal; + + /* If outside planeCircle, project on planeCircle. */ + if (absSq(result) > radiusSq) { + const Vector3 planeResult = result - planeCenter; + const float planeResultLengthSq = absSq(planeResult); + result = planeCenter + std::sqrt(planeRadiusSq / planeResultLengthSq) * planeResult; + } + } + + for (size_t i = 0; i < planeNo; ++i) { + if (planes[i].normal * (planes[i].point - result) > 0.0f) { + /* Result does not satisfy constraint i. Compute new optimal result. */ + /* Compute intersection line of plane i and plane planeNo. */ + Vector3 crossProduct = cross(planes[i].normal, planes[planeNo].normal); + + if (absSq(crossProduct) <= RVO3D_EPSILON) { + /* Planes planeNo and i are (almost) parallel, and plane i fully invalidates plane planeNo. */ + return false; + } + + Line3D line; + line.direction = normalize(crossProduct); + const Vector3 lineNormal = cross(line.direction, planes[planeNo].normal); + line.point = planes[planeNo].point + (((planes[i].point - planes[planeNo].point) * planes[i].normal) / (lineNormal * planes[i].normal)) * lineNormal; + + if (!linearProgram1(planes, i, line, radius, optVelocity, directionOpt, result)) { + return false; + } + } + } + + return true; + } + + size_t linearProgram3(const std::vector<Plane> &planes, float radius, const Vector3 &optVelocity, bool directionOpt, Vector3 &result) + { + if (directionOpt) { + /* Optimize direction. Note that the optimization velocity is of unit length in this case. */ + result = optVelocity * radius; + } + else if (absSq(optVelocity) > sqr(radius)) { + /* Optimize closest point and outside circle. */ + result = normalize(optVelocity) * radius; + } + else { + /* Optimize closest point and inside circle. */ + result = optVelocity; + } + + for (size_t i = 0; i < planes.size(); ++i) { + if (planes[i].normal * (planes[i].point - result) > 0.0f) { + /* Result does not satisfy constraint i. Compute new optimal result. */ + const Vector3 tempResult = result; + + if (!linearProgram2(planes, i, radius, optVelocity, directionOpt, result)) { + result = tempResult; + return i; + } + } + } + + return planes.size(); + } + + void linearProgram4(const std::vector<Plane> &planes, size_t beginPlane, float radius, Vector3 &result) + { + float distance = 0.0f; + + for (size_t i = beginPlane; i < planes.size(); ++i) { + if (planes[i].normal * (planes[i].point - result) > distance) { + /* Result does not satisfy constraint of plane i. */ + std::vector<Plane> projPlanes; + + for (size_t j = 0; j < i; ++j) { + Plane plane; + + const Vector3 crossProduct = cross(planes[j].normal, planes[i].normal); + + if (absSq(crossProduct) <= RVO3D_EPSILON) { + /* Plane i and plane j are (almost) parallel. */ + if (planes[i].normal * planes[j].normal > 0.0f) { + /* Plane i and plane j point in the same direction. */ + continue; + } + else { + /* Plane i and plane j point in opposite direction. */ + plane.point = 0.5f * (planes[i].point + planes[j].point); + } + } + else { + /* Plane.point is point on line of intersection between plane i and plane j. */ + const Vector3 lineNormal = cross(crossProduct, planes[i].normal); + plane.point = planes[i].point + (((planes[j].point - planes[i].point) * planes[j].normal) / (lineNormal * planes[j].normal)) * lineNormal; + } + + plane.normal = normalize(planes[j].normal - planes[i].normal); + projPlanes.push_back(plane); + } + + const Vector3 tempResult = result; + + if (linearProgram3(projPlanes, radius, planes[i].normal, true, result) < projPlanes.size()) { + /* This should in principle not happen. The result is by definition already in the feasible region of this linear program. If it fails, it is due to small floating point error, and the current result is kept. */ + result = tempResult; + } + + distance = planes[i].normal * (planes[i].point - result); + } + } + } +} diff --git a/thirdparty/rvo2/rvo2_3d/Agent3d.h b/thirdparty/rvo2/rvo2_3d/Agent3d.h index 353d64ce82..d99e3cac66 100644 --- a/thirdparty/rvo2/rvo2_3d/Agent3d.h +++ b/thirdparty/rvo2/rvo2_3d/Agent3d.h @@ -1,15 +1,14 @@ /* - * Agent3d.h + * Agent.h * RVO2-3D Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,97 +27,80 @@ * Chapel Hill, N.C. 27599-3175 * United States of America * - * <https://gamma.cs.unc.edu/RVO2/> + * <http://gamma.cs.unc.edu/RVO2/> */ -#ifndef RVO3D_AGENT_H_ -#define RVO3D_AGENT_H_ - /** - * @file Agent3d.h - * @brief Contains the Agent3D class. + * \file Agent.h + * \brief Contains the Agent class. */ +#ifndef RVO3D_AGENT_H_ +#define RVO3D_AGENT_H_ #include <cstddef> #include <cstdint> #include <utility> #include <vector> -#include "Plane.h" +#include "RVOSimulator3d.h" #include "Vector3.h" namespace RVO3D { -class RVOSimulator3D; - -/** - * @brief Defines an agent in the simulation. - */ -class Agent3D { - public: - /** - * @brief Constructs an agent instance. - * @param[in] sim The simulator instance. - */ - explicit Agent3D(); - - /** - * @brief Destroys this agent instance. - */ - ~Agent3D(); - - /** - * @brief Computes the neighbors of this agent. - */ - void computeNeighbors(RVOSimulator3D *sim_); - - /** - * @brief Computes the new velocity of this agent. - */ - void computeNewVelocity(RVOSimulator3D *sim_); - - /** - * @brief Inserts an agent neighbor into the set of neighbors of this - * agent. - * @param[in] agent A pointer to the agent to be inserted. - * @param[in] rangeSq The squared range around this agent. - */ - void insertAgentNeighbor(const Agent3D *agent, - float &rangeSq); /* NOLINT(runtime/references) */ - - /** - * @brief Updates the three-dimensional position and three-dimensional - * velocity of this agent. - */ - void update(RVOSimulator3D *sim_);; - - /* Not implemented. */ - Agent3D(const Agent3D &other); - - /* Not implemented. */ - Agent3D &operator=(const Agent3D &other); - - Vector3 newVelocity_; - Vector3 position_; - Vector3 prefVelocity_; - Vector3 velocity_; - RVOSimulator3D *sim_; - std::size_t id_; - std::size_t maxNeighbors_; - float maxSpeed_; - float neighborDist_; - float radius_; - float timeHorizon_; - float timeHorizonObst_; - std::vector<std::pair<float, const Agent3D *> > agentNeighbors_; - std::vector<Plane> orcaPlanes_; - float height_ = 1.0; - uint32_t avoidance_layers_ = 1; - uint32_t avoidance_mask_ = 1; - float avoidance_priority_ = 1.0; - - friend class KdTree3D; - friend class RVOSimulator3D; -}; -} /* namespace RVO3D */ + /** + * \brief Defines an agent in the simulation. + */ + class Agent3D { + public: + /** + * \brief Constructs an agent instance. + * \param sim The simulator instance. + */ + explicit Agent3D(); + + /** + * \brief Computes the neighbors of this agent. + */ + void computeNeighbors(RVOSimulator3D *sim_); + + /** + * \brief Computes the new velocity of this agent. + */ + void computeNewVelocity(RVOSimulator3D *sim_); + + /** + * \brief Inserts an agent neighbor into the set of neighbors of this agent. + * \param agent A pointer to the agent to be inserted. + * \param rangeSq The squared range around this agent. + */ + void insertAgentNeighbor(const Agent3D *agent, float &rangeSq); + + /** + * \brief Updates the three-dimensional position and three-dimensional velocity of this agent. + */ + void update(RVOSimulator3D *sim_); + + Vector3 newVelocity_; + Vector3 position_; + Vector3 prefVelocity_; + Vector3 velocity_; + RVOSimulator3D *sim_; + size_t id_; + size_t maxNeighbors_; + float maxSpeed_; + float neighborDist_; + float radius_; + float timeHorizon_; + float timeHorizonObst_; + std::vector<std::pair<float, const Agent3D *> > agentNeighbors_; + std::vector<Plane> orcaPlanes_; + float height_ = 1.0; + uint32_t avoidance_layers_ = 1; + uint32_t avoidance_mask_ = 1; + float avoidance_priority_ = 1.0; + + friend class KdTree3D; + friend class RVOSimulator3D; + }; +} #endif /* RVO3D_AGENT_H_ */ diff --git a/thirdparty/rvo2/rvo2_3d/Plane.cc b/thirdparty/rvo2/rvo2_3d/Definitions.h index 24c223fb26..34d1d06e0a 100644 --- a/thirdparty/rvo2/rvo2_3d/Plane.cc +++ b/thirdparty/rvo2/rvo2_3d/Definitions.h @@ -1,9 +1,8 @@ /* - * Plane.cc + * Definitions.h * RVO2-3D Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,8 +30,24 @@ * <https://gamma.cs.unc.edu/RVO2/> */ -#include "Plane.h" +/** + * \file Definitions.h + * \brief Contains functions and constants used in multiple classes. + */ + +#ifndef RVO3D_DEFINITIONS_H_ +#define RVO3D_DEFINITIONS_H_ namespace RVO3D { -Plane::Plane() {} -} /* namespace RVO3D */ + /** + * \brief Computes the square of a float. + * \param scalar The float to be squared. + * \return The square of the float. + */ + inline float sqr(float scalar) + { + return scalar * scalar; + } +} + +#endif /* RVO3D_DEFINITIONS_H_ */ diff --git a/thirdparty/rvo2/rvo2_3d/KdTree3d.cc b/thirdparty/rvo2/rvo2_3d/KdTree3d.cc deleted file mode 100644 index ac64d1560a..0000000000 --- a/thirdparty/rvo2/rvo2_3d/KdTree3d.cc +++ /dev/null @@ -1,264 +0,0 @@ -/* - * KdTree3d.cc - * RVO2-3D Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -#include "KdTree3d.h" - -#include <algorithm> -#include <utility> - -#include "Agent3d.h" -#include "RVOSimulator3d.h" -#include "Vector3.h" - -namespace RVO3D { -namespace { -/** - * @brief The maximum size of a k-D leaf node. - */ -const std::size_t RVO3D_MAX_LEAF_SIZE = 10U; -} /* namespace */ - -/** - * @brief Defines an agent k-D tree node. - */ -class KdTree3D::AgentTreeNode { - public: - /** - * @brief Constructs an agent k-D tree node. - */ - AgentTreeNode(); - - /** - * @brief The beginning node number. - */ - std::size_t begin; - - /** - * @brief The ending node number. - */ - std::size_t end; - - /** - * @brief The left node number. - */ - std::size_t left; - - /** - * @brief The right node number. - */ - std::size_t right; - - /** - * @brief The maximum coordinates. - */ - Vector3 maxCoord; - - /** - * @brief The minimum coordinates. - */ - Vector3 minCoord; -}; - -KdTree3D::AgentTreeNode::AgentTreeNode() - : begin(0U), end(0U), left(0U), right(0U) {} - -KdTree3D::KdTree3D(RVOSimulator3D *sim) : sim_(sim) {} - -KdTree3D::~KdTree3D() {} - -void KdTree3D::buildAgentTree(std::vector<Agent3D *> agents) { - agents_.swap(agents_); - - if (!agents_.empty()) { - agentTree_.resize(2U * agents_.size() - 1U); - buildAgentTreeRecursive(0U, agents_.size(), 0U); - } -} - -void KdTree3D::buildAgentTreeRecursive(std::size_t begin, std::size_t end, - std::size_t node) { - agentTree_[node].begin = begin; - agentTree_[node].end = end; - agentTree_[node].minCoord = agents_[begin]->position_; - agentTree_[node].maxCoord = agents_[begin]->position_; - - for (std::size_t i = begin + 1U; i < end; ++i) { - agentTree_[node].maxCoord[0] = - std::max(agentTree_[node].maxCoord[0], agents_[i]->position_.x()); - agentTree_[node].minCoord[0] = - std::min(agentTree_[node].minCoord[0], agents_[i]->position_.x()); - agentTree_[node].maxCoord[1] = - std::max(agentTree_[node].maxCoord[1], agents_[i]->position_.y()); - agentTree_[node].minCoord[1] = - std::min(agentTree_[node].minCoord[1], agents_[i]->position_.y()); - agentTree_[node].maxCoord[2] = - std::max(agentTree_[node].maxCoord[2], agents_[i]->position_.z()); - agentTree_[node].minCoord[2] = - std::min(agentTree_[node].minCoord[2], agents_[i]->position_.z()); - } - - if (end - begin > RVO3D_MAX_LEAF_SIZE) { - /* No leaf node. */ - std::size_t coord = 0U; - - if (agentTree_[node].maxCoord[0] - agentTree_[node].minCoord[0] > - agentTree_[node].maxCoord[1] - agentTree_[node].minCoord[1] && - agentTree_[node].maxCoord[0] - agentTree_[node].minCoord[0] > - agentTree_[node].maxCoord[2] - agentTree_[node].minCoord[2]) { - coord = 0U; - } else if (agentTree_[node].maxCoord[1] - agentTree_[node].minCoord[1] > - agentTree_[node].maxCoord[2] - agentTree_[node].minCoord[2]) { - coord = 1U; - } else { - coord = 2U; - } - - const float splitValue = 0.5F * (agentTree_[node].maxCoord[coord] + - agentTree_[node].minCoord[coord]); - - std::size_t left = begin; - - std::size_t right = end; - - while (left < right) { - while (left < right && agents_[left]->position_[coord] < splitValue) { - ++left; - } - - while (right > left && - agents_[right - 1U]->position_[coord] >= splitValue) { - --right; - } - - if (left < right) { - std::swap(agents_[left], agents_[right - 1U]); - ++left; - --right; - } - } - - std::size_t leftSize = left - begin; - - if (leftSize == 0U) { - ++leftSize; - ++left; - } - - agentTree_[node].left = node + 1U; - agentTree_[node].right = node + 2U * leftSize; - - buildAgentTreeRecursive(begin, left, agentTree_[node].left); - buildAgentTreeRecursive(left, end, agentTree_[node].right); - } -} - -void KdTree3D::computeAgentNeighbors(Agent3D *agent, float rangeSq) const { - queryAgentTreeRecursive(agent, rangeSq, 0U); -} - -void KdTree3D::queryAgentTreeRecursive(Agent3D *agent, float &rangeSq, - std::size_t node) const { - if (agentTree_[node].end - agentTree_[node].begin <= RVO3D_MAX_LEAF_SIZE) { - for (std::size_t i = agentTree_[node].begin; i < agentTree_[node].end; - ++i) { - agent->insertAgentNeighbor(agents_[i], rangeSq); - } - } else { - const float distSqLeftMinX = - std::max(0.0F, agentTree_[agentTree_[node].left].minCoord[0] - - agent->position_.x()); - const float distSqLeftMaxX = - std::max(0.0F, agent->position_.x() - - agentTree_[agentTree_[node].left].maxCoord[0]); - const float distSqLeftMinY = - std::max(0.0F, agentTree_[agentTree_[node].left].minCoord[1] - - agent->position_.y()); - const float distSqLeftMaxY = - std::max(0.0F, agent->position_.y() - - agentTree_[agentTree_[node].left].maxCoord[1]); - const float distSqLeftMinZ = - std::max(0.0F, agentTree_[agentTree_[node].left].minCoord[2] - - agent->position_.z()); - const float distSqLeftMaxZ = - std::max(0.0F, agent->position_.z() - - agentTree_[agentTree_[node].left].maxCoord[2]); - - const float distSqLeft = - distSqLeftMinX * distSqLeftMinX + distSqLeftMaxX * distSqLeftMaxX + - distSqLeftMinY * distSqLeftMinY + distSqLeftMaxY * distSqLeftMaxY + - distSqLeftMinZ * distSqLeftMinZ + distSqLeftMaxZ * distSqLeftMaxZ; - - const float distSqRightMinX = - std::max(0.0F, agentTree_[agentTree_[node].right].minCoord[0] - - agent->position_.x()); - const float distSqRightMaxX = - std::max(0.0F, agent->position_.x() - - agentTree_[agentTree_[node].right].maxCoord[0]); - const float distSqRightMinY = - std::max(0.0F, agentTree_[agentTree_[node].right].minCoord[1] - - agent->position_.y()); - const float distSqRightMaxY = - std::max(0.0F, agent->position_.y() - - agentTree_[agentTree_[node].right].maxCoord[1]); - const float distSqRightMinZ = - std::max(0.0F, agentTree_[agentTree_[node].right].minCoord[2] - - agent->position_.z()); - const float distSqRightMaxZ = - std::max(0.0F, agent->position_.z() - - agentTree_[agentTree_[node].right].maxCoord[2]); - - const float distSqRight = - distSqRightMinX * distSqRightMinX + distSqRightMaxX * distSqRightMaxX + - distSqRightMinY * distSqRightMinY + distSqRightMaxY * distSqRightMaxY + - distSqRightMinZ * distSqRightMinZ + distSqRightMaxZ * distSqRightMaxZ; - - if (distSqLeft < distSqRight) { - if (distSqLeft < rangeSq) { - queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].left); - - if (distSqRight < rangeSq) { - queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].right); - } - } - } else { - if (distSqRight < rangeSq) { - queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].right); - - if (distSqLeft < rangeSq) { - queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].left); - } - } - } - } -} -} /* namespace RVO3D */ diff --git a/thirdparty/rvo2/rvo2_3d/KdTree3d.cpp b/thirdparty/rvo2/rvo2_3d/KdTree3d.cpp new file mode 100644 index 0000000000..2534871db1 --- /dev/null +++ b/thirdparty/rvo2/rvo2_3d/KdTree3d.cpp @@ -0,0 +1,161 @@ +/* + * KdTree.cpp + * RVO2-3D Library + * + * Copyright 2008 University of North Carolina at Chapel Hill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Please send all bug reports to <geom@cs.unc.edu>. + * + * The authors may be contacted via: + * + * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha + * Dept. of Computer Science + * 201 S. Columbia St. + * Frederick P. Brooks, Jr. Computer Science Bldg. + * Chapel Hill, N.C. 27599-3175 + * United States of America + * + * <https://gamma.cs.unc.edu/RVO2/> + */ + +#include "KdTree3d.h" + +#include <algorithm> + +#include "Agent3d.h" +#include "Definitions.h" +#include "RVOSimulator3d.h" + +namespace RVO3D { + const size_t RVO3D_MAX_LEAF_SIZE = 10; + + KdTree3D::KdTree3D(RVOSimulator3D *sim) : sim_(sim) { } + + void KdTree3D::buildAgentTree(std::vector<Agent3D *> agents) + { + agents_.swap(agents); + + if (!agents_.empty()) { + agentTree_.resize(2 * agents_.size() - 1); + buildAgentTreeRecursive(0, agents_.size(), 0); + } + } + + void KdTree3D::buildAgentTreeRecursive(size_t begin, size_t end, size_t node) + { + agentTree_[node].begin = begin; + agentTree_[node].end = end; + agentTree_[node].minCoord = agents_[begin]->position_; + agentTree_[node].maxCoord = agents_[begin]->position_; + + for (size_t i = begin + 1; i < end; ++i) { + agentTree_[node].maxCoord[0] = std::max(agentTree_[node].maxCoord[0], agents_[i]->position_.x()); + agentTree_[node].minCoord[0] = std::min(agentTree_[node].minCoord[0], agents_[i]->position_.x()); + agentTree_[node].maxCoord[1] = std::max(agentTree_[node].maxCoord[1], agents_[i]->position_.y()); + agentTree_[node].minCoord[1] = std::min(agentTree_[node].minCoord[1], agents_[i]->position_.y()); + agentTree_[node].maxCoord[2] = std::max(agentTree_[node].maxCoord[2], agents_[i]->position_.z()); + agentTree_[node].minCoord[2] = std::min(agentTree_[node].minCoord[2], agents_[i]->position_.z()); + } + + if (end - begin > RVO3D_MAX_LEAF_SIZE) { + /* No leaf node. */ + size_t coord; + + if (agentTree_[node].maxCoord[0] - agentTree_[node].minCoord[0] > agentTree_[node].maxCoord[1] - agentTree_[node].minCoord[1] && agentTree_[node].maxCoord[0] - agentTree_[node].minCoord[0] > agentTree_[node].maxCoord[2] - agentTree_[node].minCoord[2]) { + coord = 0; + } + else if (agentTree_[node].maxCoord[1] - agentTree_[node].minCoord[1] > agentTree_[node].maxCoord[2] - agentTree_[node].minCoord[2]) { + coord = 1; + } + else { + coord = 2; + } + + const float splitValue = 0.5f * (agentTree_[node].maxCoord[coord] + agentTree_[node].minCoord[coord]); + + size_t left = begin; + + size_t right = end; + + while (left < right) { + while (left < right && agents_[left]->position_[coord] < splitValue) { + ++left; + } + + while (right > left && agents_[right - 1]->position_[coord] >= splitValue) { + --right; + } + + if (left < right) { + std::swap(agents_[left], agents_[right - 1]); + ++left; + --right; + } + } + + size_t leftSize = left - begin; + + if (leftSize == 0) { + ++leftSize; + ++left; + ++right; + } + + agentTree_[node].left = node + 1; + agentTree_[node].right = node + 2 * leftSize; + + buildAgentTreeRecursive(begin, left, agentTree_[node].left); + buildAgentTreeRecursive(left, end, agentTree_[node].right); + } + } + + void KdTree3D::computeAgentNeighbors(Agent3D *agent, float rangeSq) const + { + queryAgentTreeRecursive(agent, rangeSq, 0); + } + + void KdTree3D::queryAgentTreeRecursive(Agent3D *agent, float &rangeSq, size_t node) const + { + if (agentTree_[node].end - agentTree_[node].begin <= RVO3D_MAX_LEAF_SIZE) { + for (size_t i = agentTree_[node].begin; i < agentTree_[node].end; ++i) { + agent->insertAgentNeighbor(agents_[i], rangeSq); + } + } + else { + const float distSqLeft = sqr(std::max(0.0f, agentTree_[agentTree_[node].left].minCoord[0] - agent->position_.x())) + sqr(std::max(0.0f, agent->position_.x() - agentTree_[agentTree_[node].left].maxCoord[0])) + sqr(std::max(0.0f, agentTree_[agentTree_[node].left].minCoord[1] - agent->position_.y())) + sqr(std::max(0.0f, agent->position_.y() - agentTree_[agentTree_[node].left].maxCoord[1])) + sqr(std::max(0.0f, agentTree_[agentTree_[node].left].minCoord[2] - agent->position_.z())) + sqr(std::max(0.0f, agent->position_.z() - agentTree_[agentTree_[node].left].maxCoord[2])); + + const float distSqRight = sqr(std::max(0.0f, agentTree_[agentTree_[node].right].minCoord[0] - agent->position_.x())) + sqr(std::max(0.0f, agent->position_.x() - agentTree_[agentTree_[node].right].maxCoord[0])) + sqr(std::max(0.0f, agentTree_[agentTree_[node].right].minCoord[1] - agent->position_.y())) + sqr(std::max(0.0f, agent->position_.y() - agentTree_[agentTree_[node].right].maxCoord[1])) + sqr(std::max(0.0f, agentTree_[agentTree_[node].right].minCoord[2] - agent->position_.z())) + sqr(std::max(0.0f, agent->position_.z() - agentTree_[agentTree_[node].right].maxCoord[2])); + + if (distSqLeft < distSqRight) { + if (distSqLeft < rangeSq) { + queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].left); + + if (distSqRight < rangeSq) { + queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].right); + } + } + } + else { + if (distSqRight < rangeSq) { + queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].right); + + if (distSqLeft < rangeSq) { + queryAgentTreeRecursive(agent, rangeSq, agentTree_[node].left); + } + } + } + } + } +} diff --git a/thirdparty/rvo2/rvo2_3d/KdTree3d.h b/thirdparty/rvo2/rvo2_3d/KdTree3d.h index 900d9a2169..c018f98b23 100644 --- a/thirdparty/rvo2/rvo2_3d/KdTree3d.h +++ b/thirdparty/rvo2/rvo2_3d/KdTree3d.h @@ -1,9 +1,8 @@ /* - * KdTree3d.h + * KdTree.h * RVO2-3D Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,88 +29,92 @@ * * <https://gamma.cs.unc.edu/RVO2/> */ - -#ifndef RVO3D_KD_TREE_H_ -#define RVO3D_KD_TREE_H_ - /** - * @file KdTree3d.h - * @brief Contains the KdTree3D class. + * \file KdTree.h + * \brief Contains the KdTree class. */ +#ifndef RVO3D_KD_TREE_H_ +#define RVO3D_KD_TREE_H_ #include <cstddef> #include <vector> -namespace RVO3D { -class Agent3D; -class RVOSimulator3D; +#include "Vector3.h" -/** - * @brief Defines a k-D tree for agents in the simulation. - */ -class KdTree3D { - public: - class AgentTreeNode; - - /** - * @brief Constructs a k-D tree instance. - * @param[in] sim The simulator instance. - */ - explicit KdTree3D(RVOSimulator3D *sim); - - /** - * @brief Destroys this k-D tree instance. - */ - ~KdTree3D(); - - /** - * @brief Builds an agent k-D tree. - */ - void buildAgentTree(std::vector<Agent3D *> agents); - - /** - * @brief Recursive function to build a k-D tree. - * @param[in] begin The beginning k-D tree node. - * @param[in] end The ending k-D tree node. - * @param[in] node The current k-D tree node. - */ - void buildAgentTreeRecursive(std::size_t begin, std::size_t end, - std::size_t node); - - /** - * @brief Computes the agent neighbors of the specified agent. - * @param[in] agent A pointer to the agent for which agent neighbors are to - * be computed. - * @param[in] rangeSq The squared range around the agent. - */ - void computeAgentNeighbors(Agent3D *agent, float rangeSq) const; - - /** - * @brief Recursive function to compute the neighbors of the specified - * agent. - * @param[in] agent A pointer to the agent for which neighbors are to be - * computed. - * @param[in,out] rangeSq The squared range around the agent. - * @param[in] node The current k-D tree node. - */ - - void queryAgentTreeRecursive(Agent3D *agent, - float &rangeSq, /* NOLINT(runtime/references) */ - std::size_t node) const; - - /* Not implemented. */ - KdTree3D(const KdTree3D &other); - - /* Not implemented. */ - KdTree3D &operator=(const KdTree3D &other); - - std::vector<Agent3D *> agents_; - std::vector<AgentTreeNode> agentTree_; - RVOSimulator3D *sim_; - - friend class Agent3D; - friend class RVOSimulator3D; -}; -} /* namespace RVO3D */ +namespace RVO3D { + class Agent3D; + class RVOSimulator3D; + + /** + * \brief Defines <i>k</i>d-trees for agents in the simulation. + */ + class KdTree3D { + public: + /** + * \brief Defines an agent <i>k</i>d-tree node. + */ + class AgentTreeNode3D { + public: + /** + * \brief The beginning node number. + */ + size_t begin; + + /** + * \brief The ending node number. + */ + size_t end; + + /** + * \brief The left node number. + */ + size_t left; + + /** + * \brief The right node number. + */ + size_t right; + + /** + * \brief The maximum coordinates. + */ + Vector3 maxCoord; + + /** + * \brief The minimum coordinates. + */ + Vector3 minCoord; + }; + + /** + * \brief Constructs a <i>k</i>d-tree instance. + * \param sim The simulator instance. + */ + explicit KdTree3D(RVOSimulator3D *sim); + + /** + * \brief Builds an agent <i>k</i>d-tree. + */ + void buildAgentTree(std::vector<Agent3D *> agents); + + void buildAgentTreeRecursive(size_t begin, size_t end, size_t node); + + /** + * \brief Computes the agent neighbors of the specified agent. + * \param agent A pointer to the agent for which agent neighbors are to be computed. + * \param rangeSq The squared range around the agent. + */ + void computeAgentNeighbors(Agent3D *agent, float rangeSq) const; + + void queryAgentTreeRecursive(Agent3D *agent, float &rangeSq, size_t node) const; + + std::vector<Agent3D *> agents_; + std::vector<AgentTreeNode3D> agentTree_; + RVOSimulator3D *sim_; + + friend class Agent3D; + friend class RVOSimulator3D; + }; +} #endif /* RVO3D_KD_TREE_H_ */ diff --git a/thirdparty/rvo2/rvo2_3d/Plane.h b/thirdparty/rvo2/rvo2_3d/Plane.h deleted file mode 100644 index dbb1f63a80..0000000000 --- a/thirdparty/rvo2/rvo2_3d/Plane.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Plane.h - * RVO2-3D Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -#ifndef RVO3D_PLANE_H_ -#define RVO3D_PLANE_H_ - -/** - * @file Plane.h - * @brief Contains the Plane class. - */ - -#include "Vector3.h" - -namespace RVO3D { -/** - * @brief Defines a plane. - */ -class Plane { - public: - /** - * @brief Constructs a plane. - */ - Plane(); - - /** - * @brief A point on the plane. - */ - Vector3 point; - - /** - * @brief The normal to the plane. - */ - Vector3 normal; -}; -} /* namespace RVO3D */ - -#endif /* RVO3D_PLANE_H_ */ diff --git a/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.cc b/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.cc deleted file mode 100644 index 346d604497..0000000000 --- a/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.cc +++ /dev/null @@ -1,250 +0,0 @@ -/* - * RVOSimulator3d.cc - * RVO2-3D Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -#include "RVOSimulator3d.h" - -#include <utility> - -#ifdef _OPENMP -#include <omp.h> -#endif /* _OPENMP */ - -#include "Agent3d.h" -#include "KdTree3d.h" -#include "Plane.h" - -namespace RVO3D { -RVOSimulator3D::RVOSimulator3D() - : defaultAgent_(NULL), - kdTree_(new KdTree3D(this)), - globalTime_(0.0F), - timeStep_(0.0F) {} - -RVOSimulator3D::RVOSimulator3D(float timeStep, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float radius, float maxSpeed, - const Vector3 &velocity) - : defaultAgent_(new Agent3D()), - kdTree_(new KdTree3D(this)), - globalTime_(0.0F), - timeStep_(timeStep) { - defaultAgent_->maxNeighbors_ = maxNeighbors; - defaultAgent_->maxSpeed_ = maxSpeed; - defaultAgent_->neighborDist_ = neighborDist; - defaultAgent_->radius_ = radius; - defaultAgent_->timeHorizon_ = timeHorizon; - defaultAgent_->velocity_ = velocity; -} - -RVOSimulator3D::~RVOSimulator3D() { - delete defaultAgent_; - delete kdTree_; - - for (std::size_t i = 0U; i < agents_.size(); ++i) { - delete agents_[i]; - } -} - -std::size_t RVOSimulator3D::getAgentNumAgentNeighbors(std::size_t agentNo) const { - return agents_[agentNo]->agentNeighbors_.size(); -} - -std::size_t RVOSimulator3D::getAgentAgentNeighbor(std::size_t agentNo, - std::size_t neighborNo) const { - return agents_[agentNo]->agentNeighbors_[neighborNo].second->id_; -} - -std::size_t RVOSimulator3D::getAgentNumORCAPlanes(std::size_t agentNo) const { - return agents_[agentNo]->orcaPlanes_.size(); -} - -const Plane &RVOSimulator3D::getAgentORCAPlane(std::size_t agentNo, - std::size_t planeNo) const { - return agents_[agentNo]->orcaPlanes_[planeNo]; -} - -void RVOSimulator3D::removeAgent(std::size_t agentNo) { - delete agents_[agentNo]; - agents_[agentNo] = agents_.back(); - agents_.pop_back(); -} - -std::size_t RVOSimulator3D::addAgent(const Vector3 &position) { - if (defaultAgent_ == NULL) { - return RVO3D_ERROR; - } - - Agent3D *agent = new Agent3D(); - - agent->position_ = position; - agent->maxNeighbors_ = defaultAgent_->maxNeighbors_; - agent->maxSpeed_ = defaultAgent_->maxSpeed_; - agent->neighborDist_ = defaultAgent_->neighborDist_; - agent->radius_ = defaultAgent_->radius_; - agent->timeHorizon_ = defaultAgent_->timeHorizon_; - agent->velocity_ = defaultAgent_->velocity_; - - agent->id_ = agents_.size(); - - agents_.push_back(agent); - - return agents_.size() - 1U; -} - -std::size_t RVOSimulator3D::addAgent(const Vector3 &position, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float radius, float maxSpeed, - const Vector3 &velocity) { - Agent3D *agent = new Agent3D(); - - agent->position_ = position; - agent->maxNeighbors_ = maxNeighbors; - agent->maxSpeed_ = maxSpeed; - agent->neighborDist_ = neighborDist; - agent->radius_ = radius; - agent->timeHorizon_ = timeHorizon; - agent->velocity_ = velocity; - - agent->id_ = agents_.size(); - - agents_.push_back(agent); - - return agents_.size() - 1U; -} - -void RVOSimulator3D::doStep() { - kdTree_->buildAgentTree(agents_); - -#ifdef _OPENMP -#pragma omp parallel for -#endif /* _OPENMP */ - for (int i = 0; i < static_cast<int>(agents_.size()); ++i) { - agents_[i]->computeNeighbors(this); - agents_[i]->computeNewVelocity(this); - } - -#ifdef _OPENMP -#pragma omp parallel for -#endif /* _OPENMP */ - for (int i = 0; i < static_cast<int>(agents_.size()); ++i) { - agents_[i]->update(this); - } - - globalTime_ += timeStep_; -} - -std::size_t RVOSimulator3D::getAgentMaxNeighbors(std::size_t agentNo) const { - return agents_[agentNo]->maxNeighbors_; -} - -float RVOSimulator3D::getAgentMaxSpeed(std::size_t agentNo) const { - return agents_[agentNo]->maxSpeed_; -} - -float RVOSimulator3D::getAgentNeighborDist(std::size_t agentNo) const { - return agents_[agentNo]->neighborDist_; -} - -const Vector3 &RVOSimulator3D::getAgentPosition(std::size_t agentNo) const { - return agents_[agentNo]->position_; -} - -const Vector3 &RVOSimulator3D::getAgentPrefVelocity(std::size_t agentNo) const { - return agents_[agentNo]->prefVelocity_; -} - -float RVOSimulator3D::getAgentRadius(std::size_t agentNo) const { - return agents_[agentNo]->radius_; -} - -float RVOSimulator3D::getAgentTimeHorizon(std::size_t agentNo) const { - return agents_[agentNo]->timeHorizon_; -} - -const Vector3 &RVOSimulator3D::getAgentVelocity(std::size_t agentNo) const { - return agents_[agentNo]->velocity_; -} - -void RVOSimulator3D::setAgentDefaults(float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float radius, float maxSpeed, - const Vector3 &velocity) { - if (defaultAgent_ == NULL) { - defaultAgent_ = new Agent3D(); - } - - defaultAgent_->maxNeighbors_ = maxNeighbors; - defaultAgent_->maxSpeed_ = maxSpeed; - defaultAgent_->neighborDist_ = neighborDist; - defaultAgent_->radius_ = radius; - defaultAgent_->timeHorizon_ = timeHorizon; - defaultAgent_->velocity_ = velocity; -} - -void RVOSimulator3D::setAgentMaxNeighbors(std::size_t agentNo, - std::size_t maxNeighbors) { - agents_[agentNo]->maxNeighbors_ = maxNeighbors; -} - -void RVOSimulator3D::setAgentMaxSpeed(std::size_t agentNo, float maxSpeed) { - agents_[agentNo]->maxSpeed_ = maxSpeed; -} - -void RVOSimulator3D::setAgentNeighborDist(std::size_t agentNo, - float neighborDist) { - agents_[agentNo]->neighborDist_ = neighborDist; -} - -void RVOSimulator3D::setAgentPosition(std::size_t agentNo, - const Vector3 &position) { - agents_[agentNo]->position_ = position; -} - -void RVOSimulator3D::setAgentPrefVelocity(std::size_t agentNo, - const Vector3 &prefVelocity) { - agents_[agentNo]->prefVelocity_ = prefVelocity; -} - -void RVOSimulator3D::setAgentRadius(std::size_t agentNo, float radius) { - agents_[agentNo]->radius_ = radius; -} - -void RVOSimulator3D::setAgentTimeHorizon(std::size_t agentNo, float timeHorizon) { - agents_[agentNo]->timeHorizon_ = timeHorizon; -} - -void RVOSimulator3D::setAgentVelocity(std::size_t agentNo, - const Vector3 &velocity) { - agents_[agentNo]->velocity_ = velocity; -} -} /* namespace RVO3D */ diff --git a/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.cpp b/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.cpp new file mode 100644 index 0000000000..71e5aea9e2 --- /dev/null +++ b/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.cpp @@ -0,0 +1,274 @@ +/* + * RVOSimulator.cpp + * RVO2-3D Library + * + * Copyright 2008 University of North Carolina at Chapel Hill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Please send all bug reports to <geom@cs.unc.edu>. + * + * The authors may be contacted via: + * + * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha + * Dept. of Computer Science + * 201 S. Columbia St. + * Frederick P. Brooks, Jr. Computer Science Bldg. + * Chapel Hill, N.C. 27599-3175 + * United States of America + * + * <http://gamma.cs.unc.edu/RVO2/> + */ + +#include "RVOSimulator3d.h" + +#ifdef _OPENMP +#include <omp.h> +#endif + +#include "Agent3d.h" +#include "KdTree3d.h" + +namespace RVO3D { + RVOSimulator3D::RVOSimulator3D() : defaultAgent_(NULL), kdTree_(NULL), globalTime_(0.0f), timeStep_(0.0f) + { + kdTree_ = new KdTree3D(this); + } + + RVOSimulator3D::RVOSimulator3D(float timeStep, float neighborDist, size_t maxNeighbors, float timeHorizon, float radius, float maxSpeed, const Vector3 &velocity) : defaultAgent_(NULL), kdTree_(NULL), globalTime_(0.0f), timeStep_(timeStep) + { + kdTree_ = new KdTree3D(this); + defaultAgent_ = new Agent3D(); + + defaultAgent_->maxNeighbors_ = maxNeighbors; + defaultAgent_->maxSpeed_ = maxSpeed; + defaultAgent_->neighborDist_ = neighborDist; + defaultAgent_->radius_ = radius; + defaultAgent_->timeHorizon_ = timeHorizon; + defaultAgent_->velocity_ = velocity; + } + + RVOSimulator3D::~RVOSimulator3D() + { + if (defaultAgent_ != NULL) { + delete defaultAgent_; + } + + for (size_t i = 0; i < agents_.size(); ++i) { + delete agents_[i]; + } + + if (kdTree_ != NULL) { + delete kdTree_; + } + } + + size_t RVOSimulator3D::getAgentNumAgentNeighbors(size_t agentNo) const + { + return agents_[agentNo]->agentNeighbors_.size(); + } + + size_t RVOSimulator3D::getAgentAgentNeighbor(size_t agentNo, size_t neighborNo) const + { + return agents_[agentNo]->agentNeighbors_[neighborNo].second->id_; + } + + size_t RVOSimulator3D::getAgentNumORCAPlanes(size_t agentNo) const + { + return agents_[agentNo]->orcaPlanes_.size(); + } + + const Plane &RVOSimulator3D::getAgentORCAPlane(size_t agentNo, size_t planeNo) const + { + return agents_[agentNo]->orcaPlanes_[planeNo]; + } + + void RVOSimulator3D::removeAgent(size_t agentNo) + { + delete agents_[agentNo]; + agents_[agentNo] = agents_.back(); + agents_.pop_back(); + } + + size_t RVOSimulator3D::addAgent(const Vector3 &position) + { + if (defaultAgent_ == NULL) { + return RVO3D_ERROR; + } + + Agent3D *agent = new Agent3D(); + + agent->position_ = position; + agent->maxNeighbors_ = defaultAgent_->maxNeighbors_; + agent->maxSpeed_ = defaultAgent_->maxSpeed_; + agent->neighborDist_ = defaultAgent_->neighborDist_; + agent->radius_ = defaultAgent_->radius_; + agent->timeHorizon_ = defaultAgent_->timeHorizon_; + agent->velocity_ = defaultAgent_->velocity_; + + agent->id_ = agents_.size(); + + agents_.push_back(agent); + + return agents_.size() - 1; + } + + size_t RVOSimulator3D::addAgent(const Vector3 &position, float neighborDist, size_t maxNeighbors, float timeHorizon, float radius, float maxSpeed, const Vector3 &velocity) + { + Agent3D *agent = new Agent3D(); + + agent->position_ = position; + agent->maxNeighbors_ = maxNeighbors; + agent->maxSpeed_ = maxSpeed; + agent->neighborDist_ = neighborDist; + agent->radius_ = radius; + agent->timeHorizon_ = timeHorizon; + agent->velocity_ = velocity; + + agent->id_ = agents_.size(); + + agents_.push_back(agent); + + return agents_.size() - 1; + } + + void RVOSimulator3D::doStep() + { + kdTree_->buildAgentTree(agents_); + + for (int i = 0; i < static_cast<int>(agents_.size()); ++i) { + agents_[i]->computeNeighbors(this); + agents_[i]->computeNewVelocity(this); + } + + for (int i = 0; i < static_cast<int>(agents_.size()); ++i) { + agents_[i]->update(this); + } + + globalTime_ += timeStep_; + } + + size_t RVOSimulator3D::getAgentMaxNeighbors(size_t agentNo) const + { + return agents_[agentNo]->maxNeighbors_; + } + + float RVOSimulator3D::getAgentMaxSpeed(size_t agentNo) const + { + return agents_[agentNo]->maxSpeed_; + } + + float RVOSimulator3D::getAgentNeighborDist(size_t agentNo) const + { + return agents_[agentNo]->neighborDist_; + } + + const Vector3 &RVOSimulator3D::getAgentPosition(size_t agentNo) const + { + return agents_[agentNo]->position_; + } + + const Vector3 &RVOSimulator3D::getAgentPrefVelocity(size_t agentNo) const + { + return agents_[agentNo]->prefVelocity_; + } + + float RVOSimulator3D::getAgentRadius(size_t agentNo) const + { + return agents_[agentNo]->radius_; + } + + float RVOSimulator3D::getAgentTimeHorizon(size_t agentNo) const + { + return agents_[agentNo]->timeHorizon_; + } + + const Vector3 &RVOSimulator3D::getAgentVelocity(size_t agentNo) const + { + return agents_[agentNo]->velocity_; + } + + float RVOSimulator3D::getGlobalTime() const + { + return globalTime_; + } + + size_t RVOSimulator3D::getNumAgents() const + { + return agents_.size(); + } + + float RVOSimulator3D::getTimeStep() const + { + return timeStep_; + } + + void RVOSimulator3D::setAgentDefaults(float neighborDist, size_t maxNeighbors, float timeHorizon, float radius, float maxSpeed, const Vector3 &velocity) + { + if (defaultAgent_ == NULL) { + defaultAgent_ = new Agent3D(); + } + + defaultAgent_->maxNeighbors_ = maxNeighbors; + defaultAgent_->maxSpeed_ = maxSpeed; + defaultAgent_->neighborDist_ = neighborDist; + defaultAgent_->radius_ = radius; + defaultAgent_->timeHorizon_ = timeHorizon; + defaultAgent_->velocity_ = velocity; + } + + void RVOSimulator3D::setAgentMaxNeighbors(size_t agentNo, size_t maxNeighbors) + { + agents_[agentNo]->maxNeighbors_ = maxNeighbors; + } + + void RVOSimulator3D::setAgentMaxSpeed(size_t agentNo, float maxSpeed) + { + agents_[agentNo]->maxSpeed_ = maxSpeed; + } + + void RVOSimulator3D::setAgentNeighborDist(size_t agentNo, float neighborDist) + { + agents_[agentNo]->neighborDist_ = neighborDist; + } + + void RVOSimulator3D::setAgentPosition(size_t agentNo, const Vector3 &position) + { + agents_[agentNo]->position_ = position; + } + + void RVOSimulator3D::setAgentPrefVelocity(size_t agentNo, const Vector3 &prefVelocity) + { + agents_[agentNo]->prefVelocity_ = prefVelocity; + } + + void RVOSimulator3D::setAgentRadius(size_t agentNo, float radius) + { + agents_[agentNo]->radius_ = radius; + } + + void RVOSimulator3D::setAgentTimeHorizon(size_t agentNo, float timeHorizon) + { + agents_[agentNo]->timeHorizon_ = timeHorizon; + } + + void RVOSimulator3D::setAgentVelocity(size_t agentNo, const Vector3 &velocity) + { + agents_[agentNo]->velocity_ = velocity; + } + + void RVOSimulator3D::setTimeStep(float timeStep) + { + timeStep_ = timeStep; + } +} diff --git a/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.h b/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.h index 73b734a4af..4ea093d74c 100644 --- a/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.h +++ b/thirdparty/rvo2/rvo2_3d/RVOSimulator3d.h @@ -1,15 +1,14 @@ /* - * RVOSimulator3d.h + * RVOSimulator.h * RVO2-3D Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,16 +27,15 @@ * Chapel Hill, N.C. 27599-3175 * United States of America * - * <https://gamma.cs.unc.edu/RVO2/> + * <http://gamma.cs.unc.edu/RVO2/> */ -#ifndef RVO3D_RVO_SIMULATOR_H_ -#define RVO3D_RVO_SIMULATOR_H_ - /** - * @file RVOSimulator3d.h - * @brief Contains the RVOSimulator3D class. + * \file RVOSimulator.h + * \brief Contains the RVOSimulator class. */ +#ifndef RVO3D_RVO_SIMULATOR_H_ +#define RVO3D_RVO_SIMULATOR_H_ #include <cstddef> #include <limits> @@ -46,369 +44,281 @@ #include "Vector3.h" namespace RVO3D { -class Agent3D; -class KdTree3D; -class Plane; - -/** - * @brief Error value. A value equal to the largest unsigned integer, which is - * returned in case of an error by functions in RVO::RVOSimulator. - */ -const std::size_t RVO3D_ERROR = std::numeric_limits<std::size_t>::max(); - -/** - * @brief Defines the simulation. The main class of the library that contains - * all simulation functionality. - */ -class RVOSimulator3D { - public: - /** - * @brief Constructs a simulator instance. - */ - RVOSimulator3D(); - - /** - * @brief Constructs a simulator instance and sets the default properties - * for any new agent that is added. - * @param[in] timeStep The time step of the simulation. Must be positive. - * @param[in] neighborDist The default maximum distance (center point to - * center point) to other agents a new agent takes - * into account in the navigation. The larger this - * number, the longer the running time of the - * simulation. If the number is too low, the - * simulation will not be safe. Must be non-negative. - * @param[in] maxNeighbors The default maximum number of other agents a new - * agent takes into account in the navigation. The - * larger this number, the longer the running time of - * the simulation. If the number is too low, the - * simulation will not be safe. - * @param[in] timeHorizon The default minimum amount of time for which a new - * agent's velocities that are computed by the - * simulation are safe with respect to other agents. - * The larger this number, the sooner an agent will - * respond to the presence of other agents, but the - * less freedom the agent has in choosing its - * velocities. Must be positive. - * @param[in] radius The default radius of a new agent. Must be - * non-negative. - * @param[in] maxSpeed The default maximum speed of a new agent. Must be - * non-negative. - * @param[in] velocity The default initial three-dimensional linear - * velocity of a new agent (optional). - */ - RVOSimulator3D(float timeStep, float neighborDist, std::size_t maxNeighbors, - float timeHorizon, float radius, float maxSpeed, - const Vector3 &velocity = Vector3()); - - /** - * @brief Destroys this simulator instance. - */ - ~RVOSimulator3D(); - - /** - * @brief Adds a new agent with default properties to the simulation. - * @param[in] position The three-dimensional starting position of this agent. - * @return The number of the agent or RVO::RVO3D_ERROR when the agent - * defaults have not been set. - */ - std::size_t addAgent(const Vector3 &position); - - /** - * @brief Adds a new agent to the simulation. - * @param[in] position The three-dimensional starting position of this - * agent. - * @param[in] neighborDist The maximum distance (center point to center - * point) to other agents this agent takes into - * account in the navigation. The larger this number, - * the longer the running time of the simulation. If - * the number is too low, the simulation will not be - * safe. Must be non-negative. - * @param[in] maxNeighbors The maximum number of other agents this agent takes - * into account in the navigation. The larger this - * number, the longer the running time of the - * simulation. If the number is too low, the - * simulation will not be safe. - * @param[in] timeHorizon The minimum amount of time for which this agent's - * velocities that are computed by the simulation are - * safe with respect to other agents. The larger this - * number, the sooner this agent will respond to the - * presence of other agents, but the less freedom this - * agent has in choosing its velocities. Must be - * positive. - * @param[in] radius The radius of this agent. Must be non-negative. - * @param[in] maxSpeed The maximum speed of this agent. Must be - * non-negative. - * @param[in] velocity The initial three-dimensional linear velocity of - * this agent (optional). - * @return The number of the agent. - */ - std::size_t addAgent(const Vector3 &position, float neighborDist, - std::size_t maxNeighbors, float timeHorizon, - float radius, float maxSpeed, - const Vector3 &velocity = Vector3()); - - /** - * @brief Lets the simulator perform a simulation step and updates the - * three-dimensional position and three-dimensional velocity of each - * agent. - */ - void doStep(); - - /** - * @brief Returns the specified agent neighbor of the specified agent. - * @param[in] agentNo The number of the agent whose agent neighbor is to - * be retrieved. - * @param[in] neighborNo The number of the agent neighbor to be retrieved. - * @return The number of the neighboring agent. - */ - std::size_t getAgentAgentNeighbor(std::size_t agentNo, - std::size_t neighborNo) const; - - /** - * @brief Returns the maximum neighbor count of a specified agent. - * @param[in] agentNo The number of the agent whose maximum neighbor count is - * to be retrieved. - * @return The present maximum neighbor count of the agent. - */ - std::size_t getAgentMaxNeighbors(std::size_t agentNo) const; - - /** - * @brief Returns the maximum speed of a specified agent. - * @param[in] agentNo The number of the agent whose maximum speed is to be - * retrieved. - * @return The present maximum speed of the agent. - */ - float getAgentMaxSpeed(std::size_t agentNo) const; - - /** - * @brief Returns the maximum neighbor distance of a specified agent. - * @param[in] agentNo The number of the agent whose maximum neighbor distance - * is to be retrieved. - * @return The present maximum neighbor distance of the agent. - */ - float getAgentNeighborDist(std::size_t agentNo) const; - - /** - * @brief Returns the count of agent neighbors taken into account to - * compute the current velocity for the specified agent. - * @param[in] agentNo The number of the agent whose count of agent neighbors - * is to be retrieved. - * @return The count of agent neighbors taken into account to compute the - * current velocity for the specified agent. - */ - std::size_t getAgentNumAgentNeighbors(std::size_t agentNo) const; - - /** - * @brief Returns the count of ORCA constraints used to compute the - * current velocity for the specified agent. - * @param[in] agentNo The number of the agent whose count of ORCA constraints - * i to be retrieved. - * @return The count of ORCA constraints used to compute the current - * velocity for the specified agent. - */ - std::size_t getAgentNumORCAPlanes(std::size_t agentNo) const; - - /** - * @brief Returns the specified ORCA constraint of the specified agent. - * @param[in] agentNo The number of the agent whose ORCA constraint is to be - * retrieved. - * @param[in] planeNo The number of the ORCA constraint to be retrieved. - * @return A plane representing the specified ORCA constraint. - * @note The halfspace to which the normal of the plane points is the - * region of permissible velocities with respect to the specified - * ORCA constraint. - */ - const Plane &getAgentORCAPlane(std::size_t agentNo, - std::size_t planeNo) const; - - /** - * @brief Returns the three-dimensional position of a specified agent. - * @param[in] agentNo The number of the agent whose three-dimensional position - * is to be retrieved. - * @return The present three-dimensional position of the (center of the) - * agent. - */ - const Vector3 &getAgentPosition(std::size_t agentNo) const; - - /** - * @brief Returns the three-dimensional preferred velocity of a specified - * agent. - * @param[in] agentNo The number of the agent whose three-dimensional - * preferred velocity is to be retrieved. - * @return The present three-dimensional preferred velocity of the agent. - */ - const Vector3 &getAgentPrefVelocity(std::size_t agentNo) const; - - /** - * @brief Returns the radius of a specified agent. - * @param[in] agentNo The number of the agent whose radius is to be retrieved. - * @return The present radius of the agent. - */ - float getAgentRadius(std::size_t agentNo) const; - - /** - * @brief Returns the time horizon of a specified agent. - * @param[in] agentNo The number of the agent whose time horizon is to be - * retrieved. - * @return The present time horizon of the agent. - */ - float getAgentTimeHorizon(std::size_t agentNo) const; - - /** - * @brief Returns the three-dimensional linear velocity of a specified - * agent. - * @param[in] agentNo The number of the agent whose three-dimensional linear - * velocity is to be retrieved. - * @return The present three-dimensional linear velocity of the agent. - */ - const Vector3 &getAgentVelocity(std::size_t agentNo) const; - - /** - * @brief Returns the global time of the simulation. - * @return The present global time of the simulation (zero initially). - */ - float getGlobalTime() const { return globalTime_; } - /** - * @brief Returns the count of agents in the simulation. - * @return The count of agents in the simulation. - */ - std::size_t getNumAgents() const { return agents_.size(); } - - /** - * @brief Returns the time step of the simulation. - * @return The present time step of the simulation. - */ - float getTimeStep() const { return timeStep_; } - - /** - * @brief Removes an agent from the simulation. - * @param[in] agentNo The number of the agent that is to be removed. - * @note After the removal of the agent, the agent that previously had - * number getNumAgents() - 1 will now have number agentNo. - */ - void removeAgent(std::size_t agentNo); - - /** - * @brief Sets the default properties for any new agent that is added. - * @param[in] neighborDist The default maximum distance (center point to - * center point) to other agents a new agent takes - * into account in the navigation. The larger this - * number, the longer he running time of the - * simulation. If the number is too low, the - * simulation will not be safe. Must be non-negative. - * @param[in] maxNeighbors The default maximum number of other agents a new - * agent takes into account in the navigation. The - * larger this number, the longer the running time of - * the simulation. If the number is too low, the - * simulation will not be safe. - * @param[in] timeHorizon The default minimum amount of time for which a new - * agent's velocities that are computed by the - * simulation are safe with respect to other agents. - * The larger this number, the sooner an agent will - * respond to the presence of other agents, but the - * less freedom the agent has in choosing its - * velocities. Must be positive. - * @param[in] radius The default radius of a new agent. Must be - * non-negative. - * @param[in] maxSpeed The default maximum speed of a new agent. Must be - * non-negative. - * @param[in] velocity The default initial three-dimensional linear - * velocity of a new agent (optional). - */ - void setAgentDefaults(float neighborDist, std::size_t maxNeighbors, - float timeHorizon, float radius, float maxSpeed, - const Vector3 &velocity = Vector3()); - - /** - * @brief Sets the maximum neighbor count of a specified agent. - * @param[in] agentNo The number of the agent whose maximum neighbor - * count is to be modified. - * @param[in] maxNeighbors The replacement maximum neighbor count. - */ - void setAgentMaxNeighbors(std::size_t agentNo, std::size_t maxNeighbors); - - /** - * @brief Sets the maximum speed of a specified agent. - * @param[in] agentNo The number of the agent whose maximum speed is to be - * modified. - * @param[in] maxSpeed The replacement maximum speed. Must be non-negative. - */ - void setAgentMaxSpeed(std::size_t agentNo, float maxSpeed); - - /** - * @brief Sets the maximum neighbor distance of a specified agent. - * @param[in] agentNo The number of the agent whose maximum neighbor - * distance is to be modified. - * @param[in] neighborDist The replacement maximum neighbor distance. Must be - * non-negative. - */ - void setAgentNeighborDist(std::size_t agentNo, float neighborDist); - - /** - * @brief Sets the three-dimensional position of a specified agent. - * @param[in] agentNo The number of the agent whose three-dimensional - * position is to be modified. - * @param[in] position The replacement of the three-dimensional position. - */ - void setAgentPosition(std::size_t agentNo, const Vector3 &position); - - /** - * @brief Sets the three-dimensional preferred velocity of a specified - * agent. - * @param[in] agentNo The number of the agent whose three-dimensional - * preferred velocity is to be modified. - * @param[in] prefVelocity The replacement of the three-dimensional preferred - * velocity. - */ - void setAgentPrefVelocity(std::size_t agentNo, const Vector3 &prefVelocity); - - /** - * @brief Sets the radius of a specified agent. - * @param[in] agentNo The number of the agent whose radius is to be modified. - * @param[in] radius The replacement radius. Must be non-negative. - */ - void setAgentRadius(std::size_t agentNo, float radius); - - /** - * @brief Sets the time horizon of a specified agent with respect to other - * agents. - * @param[in] agentNo The number of the agent whose time horizon is to be - * modified. - * @param[in] timeHorizon The replacement time horizon with respect to other - * agents. Must be positive. - */ - void setAgentTimeHorizon(std::size_t agentNo, float timeHorizon); - - /** - * @brief Sets the three-dimensional linear velocity of a specified agent. - * @param[in] agentNo The number of the agent whose three-dimensional linear - * velocity is to be modified. - * @param[in] velocity The replacement three-dimensional linear velocity. - */ - void setAgentVelocity(std::size_t agentNo, const Vector3 &velocity); - - /** - * @brief Sets the time step of the simulation. - * @param[in] timeStep The time step of the simulation. Must be positive. - */ - void setTimeStep(float timeStep) { timeStep_ = timeStep; } - - public: - /* Not implemented. */ - RVOSimulator3D(const RVOSimulator3D &other); - - /* Not implemented. */ - RVOSimulator3D &operator=(const RVOSimulator3D &other); - - Agent3D *defaultAgent_; - KdTree3D *kdTree_; - float globalTime_; - float timeStep_; - std::vector<Agent3D *> agents_; - - friend class Agent3D; - friend class KdTree3D; -}; -} /* namespace RVO3D */ - -#endif /* RVO3D_RVO_SIMULATOR_H_ */ + class Agent3D; + class KdTree3D; + + /** + * \brief Error value. + * + * A value equal to the largest unsigned integer, which is returned in case of an error by functions in RVO3D::RVOSimulator. + */ + const size_t RVO3D_ERROR = std::numeric_limits<size_t>::max(); + + /** + * \brief Defines a plane. + */ + class Plane { + public: + /** + * \brief A point on the plane. + */ + Vector3 point; + + /** + * \brief The normal to the plane. + */ + Vector3 normal; + }; + + /** + * \brief Defines the simulation. + * + * The main class of the library that contains all simulation functionality. + */ + class RVOSimulator3D { + public: + /** + * \brief Constructs a simulator instance. + */ + RVOSimulator3D(); + + /** + * \brief Constructs a simulator instance and sets the default properties for any new agent that is added. + * \param timeStep The time step of the simulation. Must be positive. + * \param neighborDist The default maximum distance (center point to center point) to other agents a new agent takes into account in the navigation. The larger this number, the longer he running time of the simulation. If the number is too low, the simulation will not be safe. Must be non-negative. + * \param maxNeighbors The default maximum number of other agents a new agent takes into account in the navigation. The larger this number, the longer the running time of the simulation. If the number is too low, the simulation will not be safe. + * \param timeHorizon The default minimum amount of time for which a new agent's velocities that are computed by the simulation are safe with respect to other agents. The larger this number, the sooner an agent will respond to the presence of other agents, but the less freedom the agent has in choosing its velocities. Must be positive. + * \param radius The default radius of a new agent. Must be non-negative. + * \param maxSpeed The default maximum speed of a new agent. Must be non-negative. + * \param velocity The default initial three-dimensional linear velocity of a new agent (optional). + */ + RVOSimulator3D(float timeStep, float neighborDist, size_t maxNeighbors, float timeHorizon, float radius, float maxSpeed, const Vector3 &velocity = Vector3()); + + /** + * \brief Destroys this simulator instance. + */ + ~RVOSimulator3D(); + + /** + * \brief Adds a new agent with default properties to the simulation. + * \param position The three-dimensional starting position of this agent. + * \return The number of the agent, or RVO3D::RVO3D_ERROR when the agent defaults have not been set. + */ + size_t addAgent(const Vector3 &position); + + /** + * \brief Adds a new agent to the simulation. + * \param position The three-dimensional starting position of this agent. + * \param neighborDist The maximum distance (center point to center point) to other agents this agent takes into account in the navigation. The larger this number, the longer the running time of the simulation. If the number is too low, the simulation will not be safe. Must be non-negative. + * \param maxNeighbors The maximum number of other agents this agent takes into account in the navigation. The larger this number, the longer the running time of the simulation. If the number is too low, the simulation will not be safe. + * \param timeHorizon The minimum amount of time for which this agent's velocities that are computed by the simulation are safe with respect to other agents. The larger this number, the sooner this agent will respond to the presence of other agents, but the less freedom this agent has in choosing its velocities. Must be positive. + * \param radius The radius of this agent. Must be non-negative. + * \param maxSpeed The maximum speed of this agent. Must be non-negative. + * \param velocity The initial three-dimensional linear velocity of this agent (optional). + * \return The number of the agent. + */ + size_t addAgent(const Vector3 &position, float neighborDist, size_t maxNeighbors, float timeHorizon, float radius, float maxSpeed, const Vector3 &velocity = Vector3()); + + /** + * \brief Lets the simulator perform a simulation step and updates the three-dimensional position and three-dimensional velocity of each agent. + */ + void doStep(); + + /** + * \brief Returns the specified agent neighbor of the specified agent. + * \param agentNo The number of the agent whose agent neighbor is to be retrieved. + * \param neighborNo The number of the agent neighbor to be retrieved. + * \return The number of the neighboring agent. + */ + size_t getAgentAgentNeighbor(size_t agentNo, size_t neighborNo) const; + + /** + * \brief Returns the maximum neighbor count of a specified agent. + * \param agentNo The number of the agent whose maximum neighbor count is to be retrieved. + * \return The present maximum neighbor count of the agent. + */ + size_t getAgentMaxNeighbors(size_t agentNo) const; + + /** + * \brief Returns the maximum speed of a specified agent. + * \param agentNo The number of the agent whose maximum speed is to be retrieved. + * \return The present maximum speed of the agent. + */ + float getAgentMaxSpeed(size_t agentNo) const; + + /** + * \brief Returns the maximum neighbor distance of a specified agent. + * \param agentNo The number of the agent whose maximum neighbor distance is to be retrieved. + * \return The present maximum neighbor distance of the agent. + */ + float getAgentNeighborDist(size_t agentNo) const; + + /** + * \brief Returns the count of agent neighbors taken into account to compute the current velocity for the specified agent. + * \param agentNo The number of the agent whose count of agent neighbors is to be retrieved. + * \return The count of agent neighbors taken into account to compute the current velocity for the specified agent. + */ + size_t getAgentNumAgentNeighbors(size_t agentNo) const; + + /** + * \brief Returns the count of ORCA constraints used to compute the current velocity for the specified agent. + * \param agentNo The number of the agent whose count of ORCA constraints is to be retrieved. + * \return The count of ORCA constraints used to compute the current velocity for the specified agent. + */ + size_t getAgentNumORCAPlanes(size_t agentNo) const; + + /** + * \brief Returns the specified ORCA constraint of the specified agent. + * \param agentNo The number of the agent whose ORCA constraint is to be retrieved. + * \param planeNo The number of the ORCA constraint to be retrieved. + * \return A plane representing the specified ORCA constraint. + * \note The halfspace to which the normal of the plane points is the region of permissible velocities with respect to the specified ORCA constraint. + */ + const Plane &getAgentORCAPlane(size_t agentNo, size_t planeNo) const; + + /** + * \brief Returns the three-dimensional position of a specified agent. + * \param agentNo The number of the agent whose three-dimensional position is to be retrieved. + * \return The present three-dimensional position of the (center of the) agent. + */ + const Vector3 &getAgentPosition(size_t agentNo) const; + + /** + * \brief Returns the three-dimensional preferred velocity of a specified agent. + * \param agentNo The number of the agent whose three-dimensional preferred velocity is to be retrieved. + * \return The present three-dimensional preferred velocity of the agent. + */ + const Vector3 &getAgentPrefVelocity(size_t agentNo) const; + + /** + * \brief Returns the radius of a specified agent. + * \param agentNo The number of the agent whose radius is to be retrieved. + * \return The present radius of the agent. + */ + float getAgentRadius(size_t agentNo) const; + + /** + * \brief Returns the time horizon of a specified agent. + * \param agentNo The number of the agent whose time horizon is to be retrieved. + * \return The present time horizon of the agent. + */ + float getAgentTimeHorizon(size_t agentNo) const; + + /** + * \brief Returns the three-dimensional linear velocity of a specified agent. + * \param agentNo The number of the agent whose three-dimensional linear velocity is to be retrieved. + * \return The present three-dimensional linear velocity of the agent. + */ + const Vector3 &getAgentVelocity(size_t agentNo) const; + + /** + * \brief Returns the global time of the simulation. + * \return The present global time of the simulation (zero initially). + */ + float getGlobalTime() const; + + /** + * \brief Returns the count of agents in the simulation. + * \return The count of agents in the simulation. + */ + size_t getNumAgents() const; + + /** + * \brief Returns the time step of the simulation. + * \return The present time step of the simulation. + */ + float getTimeStep() const; + + /** + * \brief Removes an agent from the simulation. + * \param agentNo The number of the agent that is to be removed. + * \note After the removal of the agent, the agent that previously had number getNumAgents() - 1 will now have number agentNo. + */ + void removeAgent(size_t agentNo); + + /** + * \brief Sets the default properties for any new agent that is added. + * \param neighborDist The default maximum distance (center point to center point) to other agents a new agent takes into account in the navigation. The larger this number, the longer he running time of the simulation. If the number is too low, the simulation will not be safe. Must be non-negative. + * \param maxNeighbors The default maximum number of other agents a new agent takes into account in the navigation. The larger this number, the longer the running time of the simulation. If the number is too low, the simulation will not be safe. + * \param timeHorizon The default minimum amount of time for which a new agent's velocities that are computed by the simulation are safe with respect to other agents. The larger this number, the sooner an agent will respond to the presence of other agents, but the less freedom the agent has in choosing its velocities. Must be positive. + * \param radius The default radius of a new agent. Must be non-negative. + * \param maxSpeed The default maximum speed of a new agent. Must be non-negative. + * \param velocity The default initial three-dimensional linear velocity of a new agent (optional). + */ + void setAgentDefaults(float neighborDist, size_t maxNeighbors, float timeHorizon, float radius, float maxSpeed, const Vector3 &velocity = Vector3()); + + /** + * \brief Sets the maximum neighbor count of a specified agent. + * \param agentNo The number of the agent whose maximum neighbor count is to be modified. + * \param maxNeighbors The replacement maximum neighbor count. + */ + void setAgentMaxNeighbors(size_t agentNo, size_t maxNeighbors); + + /** + * \brief Sets the maximum speed of a specified agent. + * \param agentNo The number of the agent whose maximum speed is to be modified. + * \param maxSpeed The replacement maximum speed. Must be non-negative. + */ + void setAgentMaxSpeed(size_t agentNo, float maxSpeed); + + /** + * \brief Sets the maximum neighbor distance of a specified agent. + * \param agentNo The number of the agent whose maximum neighbor distance is to be modified. + * \param neighborDist The replacement maximum neighbor distance. Must be non-negative. + */ + void setAgentNeighborDist(size_t agentNo, float neighborDist); + + /** + * \brief Sets the three-dimensional position of a specified agent. + * \param agentNo The number of the agent whose three-dimensional position is to be modified. + * \param position The replacement of the three-dimensional position. + */ + void setAgentPosition(size_t agentNo, const Vector3 &position); + + /** + * \brief Sets the three-dimensional preferred velocity of a specified agent. + * \param agentNo The number of the agent whose three-dimensional preferred velocity is to be modified. + * \param prefVelocity The replacement of the three-dimensional preferred velocity. + */ + void setAgentPrefVelocity(size_t agentNo, const Vector3 &prefVelocity); + + /** + * \brief Sets the radius of a specified agent. + * \param agentNo The number of the agent whose radius is to be modified. + * \param radius The replacement radius. Must be non-negative. + */ + void setAgentRadius(size_t agentNo, float radius); + + /** + * \brief Sets the time horizon of a specified agent with respect to other agents. + * \param agentNo The number of the agent whose time horizon is to be modified. + * \param timeHorizon The replacement time horizon with respect to other agents. Must be positive. + */ + void setAgentTimeHorizon(size_t agentNo, float timeHorizon); + + /** + * \brief Sets the three-dimensional linear velocity of a specified agent. + * \param agentNo The number of the agent whose three-dimensional linear velocity is to be modified. + * \param velocity The replacement three-dimensional linear velocity. + */ + void setAgentVelocity(size_t agentNo, const Vector3 &velocity); + + /** + * \brief Sets the time step of the simulation. + * \param timeStep The time step of the simulation. Must be positive. + */ + void setTimeStep(float timeStep); + + public: + Agent3D *defaultAgent_; + KdTree3D *kdTree_; + float globalTime_; + float timeStep_; + std::vector<Agent3D *> agents_; + + friend class Agent3D; + friend class KdTree3D; + }; +} + +#endif diff --git a/thirdparty/rvo2/rvo2_3d/Vector3.cc b/thirdparty/rvo2/rvo2_3d/Vector3.cc deleted file mode 100644 index 95831d3c90..0000000000 --- a/thirdparty/rvo2/rvo2_3d/Vector3.cc +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Vector3.cc - * RVO2-3D Library - * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Please send all bug reports to <geom@cs.unc.edu>. - * - * The authors may be contacted via: - * - * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha - * Dept. of Computer Science - * 201 S. Columbia St. - * Frederick P. Brooks, Jr. Computer Science Bldg. - * Chapel Hill, N.C. 27599-3175 - * United States of America - * - * <https://gamma.cs.unc.edu/RVO2/> - */ - -#include "Vector3.h" - -#include <cmath> -#include <ostream> - -namespace RVO3D { -Vector3::Vector3() : val_() { - val_[0] = 0.0F; - val_[1] = 0.0F; - val_[2] = 0.0F; -} - -Vector3::Vector3(const Vector3 &vector) : val_() { - val_[0] = vector[0]; - val_[1] = vector[1]; - val_[2] = vector[2]; -} - -Vector3::Vector3(const float val[3]) : val_() { - val_[0] = val[0]; - val_[1] = val[1]; - val_[2] = val[2]; -} - -Vector3::Vector3(float x, float y, float z) : val_() { - val_[0] = x; - val_[1] = y; - val_[2] = z; -} - -Vector3::~Vector3() {} - -Vector3 &Vector3::operator=(const Vector3 &vector) { - if (this != &vector) { - val_[0] = vector[0]; - val_[1] = vector[1]; - val_[2] = vector[2]; - } - - return *this; -} - -float Vector3::operator[](std::size_t i) const { return val_[i]; } - -float &Vector3::operator[](std::size_t i) { return val_[i]; } - -Vector3 Vector3::operator-() const { - return Vector3(-val_[0], -val_[1], -val_[2]); -} - -float Vector3::operator*(const Vector3 &vector) const { - return val_[0] * vector[0] + val_[1] * vector[1] + val_[2] * vector[2]; -} - -Vector3 Vector3::operator*(float scalar) const { - return Vector3(val_[0] * scalar, val_[1] * scalar, val_[2] * scalar); -} - -Vector3 Vector3::operator/(float scalar) const { - const float invScalar = 1.0F / scalar; - - return Vector3(val_[0] * invScalar, val_[1] * invScalar, val_[2] * invScalar); -} - -Vector3 Vector3::operator+(const Vector3 &vector) const { - return Vector3(val_[0] + vector[0], val_[1] + vector[1], val_[2] + vector[2]); -} - -Vector3 Vector3::operator-(const Vector3 &vector) const { - return Vector3(val_[0] - vector[0], val_[1] - vector[1], val_[2] - vector[2]); -} - -bool Vector3::operator==(const Vector3 &vector) const { - return val_[0] == vector[0] && val_[1] == vector[1] && val_[2] == vector[2]; -} - -bool Vector3::operator!=(const Vector3 &vector) const { - return val_[0] != vector[0] || val_[1] != vector[1] || val_[2] != vector[2]; -} - -Vector3 &Vector3::operator*=(float scalar) { - val_[0] *= scalar; - val_[1] *= scalar; - val_[2] *= scalar; - - return *this; -} - -Vector3 &Vector3::operator/=(float scalar) { - const float invScalar = 1.0F / scalar; - - val_[0] *= invScalar; - val_[1] *= invScalar; - val_[2] *= invScalar; - - return *this; -} - -Vector3 &Vector3::operator+=(const Vector3 &vector) { - val_[0] += vector[0]; - val_[1] += vector[1]; - val_[2] += vector[2]; - - return *this; -} - -Vector3 &Vector3::operator-=(const Vector3 &vector) { - val_[0] -= vector[0]; - val_[1] -= vector[1]; - val_[2] -= vector[2]; - - return *this; -} - -Vector3 operator*(float scalar, const Vector3 &vector) { - return Vector3(scalar * vector[0], scalar * vector[1], scalar * vector[2]); -} - -std::ostream &operator<<(std::ostream &stream, const Vector3 &vector) { - stream << "(" << vector[0] << "," << vector[1] << "," << vector[2] << ")"; - - return stream; -} - -float abs(const Vector3 &vector) { return std::sqrt(vector * vector); } - -float absSq(const Vector3 &vector) { return vector * vector; } - -Vector3 cross(const Vector3 &vector1, const Vector3 &vector2) { - return Vector3(vector1[1] * vector2[2] - vector1[2] * vector2[1], - vector1[2] * vector2[0] - vector1[0] * vector2[2], - vector1[0] * vector2[1] - vector1[1] * vector2[0]); -} - -Vector3 normalize(const Vector3 &vector) { return vector / abs(vector); } - -} /* namespace RVO3D */ diff --git a/thirdparty/rvo2/rvo2_3d/Vector3.h b/thirdparty/rvo2/rvo2_3d/Vector3.h index 8f4708942f..6fa4bb074c 100644 --- a/thirdparty/rvo2/rvo2_3d/Vector3.h +++ b/thirdparty/rvo2/rvo2_3d/Vector3.h @@ -2,8 +2,7 @@ * Vector3.h * RVO2-3D Library * - * SPDX-FileCopyrightText: 2008 University of North Carolina at Chapel Hill - * SPDX-License-Identifier: Apache-2.0 + * Copyright 2008 University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,284 +30,324 @@ * <https://gamma.cs.unc.edu/RVO2/> */ -#ifndef RVO3D_VECTOR3_H_ -#define RVO3D_VECTOR3_H_ - /** - * @file Vector3.h - * @brief Contains the Vector3 class. + * \file Vector3.h + * \brief Contains the Vector3 class. */ +#ifndef RVO3D_VECTOR3_H_ +#define RVO3D_VECTOR3_H_ +#include <cmath> #include <cstddef> -#include <iosfwd> +#include <ostream> namespace RVO3D { -/** - * @brief Defines a three-dimensional vector. - */ -class Vector3 { - public: - /** - * @brief Constructs and initializes a three-dimensional vector instance to - * zero. - */ - Vector3(); - - /** - * @brief Constructs and initializes a three-dimensional vector from the - * specified three-dimensional vector. - * @param[in] vector The three-dimensional vector containing the - * xyz-coordinates. - */ - Vector3(const Vector3 &vector); - - /** - * @brief Constructs and initializes a three-dimensional vector from the - * specified three-element array. - * @param[in] val The three-element array containing the xyz-coordinates. - */ - explicit Vector3(const float val[3]); - - /** - * @brief Constructs and initializes a three-dimensional vector from the - * specified xyz-coordinates. - * @param[in] x The x-coordinate of the three-dimensional vector. - * @param[in] y The y-coordinate of the three-dimensional vector. - * @param[in] z The z-coordinate of the three-dimensional vector. - */ - Vector3(float x, float y, float z); - - /** - * @brief Destroys this three-dimensional vector instance. - */ - ~Vector3(); - - /** - * @brief Returns the x-coordinate of this three-dimensional vector. - * @return The x-coordinate of the three-dimensional vector. - */ - float x() const { return val_[0]; } - - /** - * @brief Returns the y-coordinate of this three-dimensional vector. - * @return The y-coordinate of the three-dimensional vector. - */ - float y() const { return val_[1]; } - - /** - * @brief Returns the z-coordinate of this three-dimensional vector. - * @return The z-coordinate of the three-dimensional vector. - */ - float z() const { return val_[2]; } - - /** - * @brief Assigns a copy of the specified three-dimensional vector to - * this three-dimensional vector instance. - * @param[in] vector The three-dimensional vector containing the - * xyz-coordinates. - * @return A reference to this three-dimensional vector instance. - */ - Vector3 &operator=(const Vector3 &vector); - - /** - * @brief Returns the specified coordinate of this three-dimensional - * vector. - * @param[in] i The coordinate that should be returned (0 <= i < 3). - * @return The specified coordinate of the three-dimensional vector. - */ - float operator[](std::size_t i) const; - - /** - * @brief Returns a reference to the specified coordinate of this - * three-dimensional vector. - * @param[in] i The coordinate to which a reference should be returned - * (0 <= i < 3). - * @return A reference to the specified coordinate of the three-dimensional - * vector. - */ - float &operator[](std::size_t i); - - /** - * @brief Computes the negation of this three-dimensional vector. - * @return The negation of this three-dimensional vector. - */ - Vector3 operator-() const; - - /** - * @brief Computes the dot product of this three-dimensional vector with - * the specified three-dimensional vector. - * @param[in] vector The three-dimensional vector with which the dot product - * should be computed. - * @return The dot product of this three-dimensional vector with a - * specified three-dimensional vector. - */ - float operator*(const Vector3 &vector) const; - - /** - * @brief Computes the scalar multiplication of this three-dimensional - * vector with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar multiplication - * should be computed. - * @return The scalar multiplication of this three-dimensional vector with - * a specified scalar value. - */ - Vector3 operator*(float scalar) const; - - /** - * @brief Computes the scalar division of this three-dimensional vector - * with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar division should be - * computed. - * @return The scalar division of this three-dimensional vector with a - * specified scalar value. - */ - Vector3 operator/(float scalar) const; - - /** - * @brief Computes the vector sum of this three-dimensional vector with - * the specified three-dimensional vector. - * @param[in] vector The three-dimensional vector with which the vector sum - * should be computed. - * @return The vector sum of this three-dimensional vector with a specified - * three-dimensional vector. - */ - Vector3 operator+(const Vector3 &vector) const; - - /** - * @brief Computes the vector difference of this three-dimensional vector - * with the specified three-dimensional vector. - * @param[in] vector The three-dimensional vector with which the vector - * difference should be computed. - * @return The vector difference of this three-dimensional vector with a - * specified three-dimensional vector. - */ - Vector3 operator-(const Vector3 &vector) const; - - /** - * @brief Tests this three-dimensional vector for equality with the - * specified three-dimensional vector. - * @param[in] vector The three-dimensional vector with which to test for - * equality. - * @return True if the three-dimensional vectors are equal. - */ - bool operator==(const Vector3 &vector) const; - - /** - * @brief Tests this three-dimensional vector for inequality with the - * specified three-dimensional vector - * @param[in] vector The three-dimensional vector with which to test for - * inequality. - * @return True if the three-dimensional vectors are not equal. - */ - bool operator!=(const Vector3 &vector) const; - - /** - * @brief Sets the value of this three-dimensional vector to the scalar - * multiplication of itself with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar multiplication - * should be computed. - * @return A reference to this three-dimensional vector. - */ - Vector3 &operator*=(float scalar); - - /** - * @brief Sets the value of this three-dimensional vector to the scalar - * division of itself with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar division should be - * computed. - * @return A reference to this three-dimensional vector. - */ - Vector3 &operator/=(float scalar); - - /** - * @brief Sets the value of this three-dimensional vector to the vector - * sum of itself with the specified three-dimensional vector. - * @param[in] vector The three-dimensional vector with which the vector sum - * should be computed. - * @return A reference to this three-dimensional vector. - */ - Vector3 &operator+=(const Vector3 &vector); - - /** - * @brief Sets the value of this three-dimensional vector to the vector - * difference of itself with the specified three-dimensional - * vector. - * @param[in] vector The three-dimensional vector with which the vector - * difference should be computed. - * @return A reference to this three-dimensional vector. - */ - Vector3 &operator-=(const Vector3 &vector); - - private: - float val_[3]; -}; - -/** - * @relates Vector3 - * @brief Computes the scalar multiplication of the specified - * three-dimensional vector with the specified scalar value. - * @param[in] scalar The scalar value with which the scalar multiplication - * should be computed. - * @param[in] vector The three-dimensional vector with which the scalar - * multiplication should be computed. - * @return The scalar multiplication of the three-dimensional vector with the - * scalar value. - */ -Vector3 operator*(float scalar, const Vector3 &vector); - -/** - * @relates Vector3 - * @brief Inserts the specified three-dimensional vector into the - * specified output stream. - * @param[in,out] os The output stream into which the three-dimensional - * vector should be inserted. - * @param[in] vector The three-dimensional vector which to insert into the - * output stream. - * @return A reference to the output stream. - */ -std::ostream &operator<<(std::ostream &stream, - const Vector3 &vector); - -/** - * @relates Vector3 - * @brief Computes the length of a specified three-dimensional vector. - * @param[in] vector The three-dimensional vector whose length is to be - * computed. - * @return The length of the three-dimensional vector. - */ -float abs(const Vector3 &vector); - -/** - * @relates Vector3 - * @brief Computes the squared length of a specified three-dimensional - * vector. - * @param[in] vector The three-dimensional vector whose squared length is to be - * computed. - * @return The squared length of the three-dimensional vector. - */ -float absSq(const Vector3 &vector); - -/** - * @relates Vector3 - * @brief Computes the cross product of the specified three-dimensional - * vectors. - * @param[in] vector1 The first vector with which the cross product should be - * computed. - * @param[in] vector2 The second vector with which the cross product should be - * computed. - * @return The cross product of the two specified vectors. - */ -Vector3 cross(const Vector3 &vector1, const Vector3 &vector2); - -/** - * @relates Vector3 - * @brief Computes the normalization of the specified three-dimensiona - * vector. - * @param[in] vector The three-dimensional vector whose normalization is to be - * computed. - * @return The normalization of the three-dimensional vector. - */ -Vector3 normalize(const Vector3 &vector); -} /* namespace RVO3D */ - -#endif /* RVO3D_VECTOR3_H_ */ + /** + * \brief Defines a three-dimensional vector. + */ + class Vector3 { + public: + /** + * \brief Constructs and initializes a three-dimensional vector instance to zero. + */ + inline Vector3() + { + val_[0] = 0.0f; + val_[1] = 0.0f; + val_[2] = 0.0f; + } + + /** + * \brief Constructs and initializes a three-dimensional vector from the specified three-dimensional vector. + * \param vector The three-dimensional vector containing the xyz-coordinates. + */ + inline Vector3(const Vector3 &vector) + { + val_[0] = vector[0]; + val_[1] = vector[1]; + val_[2] = vector[2]; + } + + /** + * \brief Constructs and initializes a three-dimensional vector from the specified three-element array. + * \param val The three-element array containing the xyz-coordinates. + */ + inline explicit Vector3(const float val[3]) + { + val_[0] = val[0]; + val_[1] = val[1]; + val_[2] = val[2]; + } + + /** + * \brief Constructs and initializes a three-dimensional vector from the specified xyz-coordinates. + * \param x The x-coordinate of the three-dimensional vector. + * \param y The y-coordinate of the three-dimensional vector. + * \param z The z-coordinate of the three-dimensional vector. + */ + inline Vector3(float x, float y, float z) + { + val_[0] = x; + val_[1] = y; + val_[2] = z; + } + + /** + * \brief Returns the x-coordinate of this three-dimensional vector. + * \return The x-coordinate of the three-dimensional vector. + */ + inline float x() const { return val_[0]; } + + /** + * \brief Returns the y-coordinate of this three-dimensional vector. + * \return The y-coordinate of the three-dimensional vector. + */ + inline float y() const { return val_[1]; } + + /** + * \brief Returns the z-coordinate of this three-dimensional vector. + * \return The z-coordinate of the three-dimensional vector. + */ + inline float z() const { return val_[2]; } + + /** + * \brief Returns the specified coordinate of this three-dimensional vector. + * \param i The coordinate that should be returned (0 <= i < 3). + * \return The specified coordinate of the three-dimensional vector. + */ + inline float operator[](size_t i) const { return val_[i]; } + + /** + * \brief Returns a reference to the specified coordinate of this three-dimensional vector. + * \param i The coordinate to which a reference should be returned (0 <= i < 3). + * \return A reference to the specified coordinate of the three-dimensional vector. + */ + inline float &operator[](size_t i) { return val_[i]; } + + /** + * \brief Computes the negation of this three-dimensional vector. + * \return The negation of this three-dimensional vector. + */ + inline Vector3 operator-() const + { + return Vector3(-val_[0], -val_[1], -val_[2]); + } + + /** + * \brief Computes the dot product of this three-dimensional vector with the specified three-dimensional vector. + * \param vector The three-dimensional vector with which the dot product should be computed. + * \return The dot product of this three-dimensional vector with a specified three-dimensional vector. + */ + inline float operator*(const Vector3 &vector) const + { + return val_[0] * vector[0] + val_[1] * vector[1] + val_[2] * vector[2]; + } + + /** + * \brief Computes the scalar multiplication of this three-dimensional vector with the specified scalar value. + * \param scalar The scalar value with which the scalar multiplication should be computed. + * \return The scalar multiplication of this three-dimensional vector with a specified scalar value. + */ + inline Vector3 operator*(float scalar) const + { + return Vector3(val_[0] * scalar, val_[1] * scalar, val_[2] * scalar); + } + + /** + * \brief Computes the scalar division of this three-dimensional vector with the specified scalar value. + * \param scalar The scalar value with which the scalar division should be computed. + * \return The scalar division of this three-dimensional vector with a specified scalar value. + */ + inline Vector3 operator/(float scalar) const + { + const float invScalar = 1.0f / scalar; + + return Vector3(val_[0] * invScalar, val_[1] * invScalar, val_[2] * invScalar); + } + + /** + * \brief Computes the vector sum of this three-dimensional vector with the specified three-dimensional vector. + * \param vector The three-dimensional vector with which the vector sum should be computed. + * \return The vector sum of this three-dimensional vector with a specified three-dimensional vector. + */ + inline Vector3 operator+(const Vector3 &vector) const + { + return Vector3(val_[0] + vector[0], val_[1] + vector[1], val_[2] + vector[2]); + } + + /** + * \brief Computes the vector difference of this three-dimensional vector with the specified three-dimensional vector. + * \param vector The three-dimensional vector with which the vector difference should be computed. + * \return The vector difference of this three-dimensional vector with a specified three-dimensional vector. + */ + inline Vector3 operator-(const Vector3 &vector) const + { + return Vector3(val_[0] - vector[0], val_[1] - vector[1], val_[2] - vector[2]); + } + + /** + * \brief Tests this three-dimensional vector for equality with the specified three-dimensional vector. + * \param vector The three-dimensional vector with which to test for equality. + * \return True if the three-dimensional vectors are equal. + */ + inline bool operator==(const Vector3 &vector) const + { + return val_[0] == vector[0] && val_[1] == vector[1] && val_[2] == vector[2]; + } + + /** + * \brief Tests this three-dimensional vector for inequality with the specified three-dimensional vector. + * \param vector The three-dimensional vector with which to test for inequality. + * \return True if the three-dimensional vectors are not equal. + */ + inline bool operator!=(const Vector3 &vector) const + { + return val_[0] != vector[0] || val_[1] != vector[1] || val_[2] != vector[2]; + } + + /** + * \brief Sets the value of this three-dimensional vector to the scalar multiplication of itself with the specified scalar value. + * \param scalar The scalar value with which the scalar multiplication should be computed. + * \return A reference to this three-dimensional vector. + */ + inline Vector3 &operator*=(float scalar) + { + val_[0] *= scalar; + val_[1] *= scalar; + val_[2] *= scalar; + + return *this; + } + + /** + * \brief Sets the value of this three-dimensional vector to the scalar division of itself with the specified scalar value. + * \param scalar The scalar value with which the scalar division should be computed. + * \return A reference to this three-dimensional vector. + */ + inline Vector3 &operator/=(float scalar) + { + const float invScalar = 1.0f / scalar; + + val_[0] *= invScalar; + val_[1] *= invScalar; + val_[2] *= invScalar; + + return *this; + } + + /** + * \brief Sets the value of this three-dimensional vector to the vector + * sum of itself with the specified three-dimensional vector. + * \param vector The three-dimensional vector with which the vector sum should be computed. + * \return A reference to this three-dimensional vector. + */ + inline Vector3 &operator+=(const Vector3 &vector) + { + val_[0] += vector[0]; + val_[1] += vector[1]; + val_[2] += vector[2]; + + return *this; + } + + /** + * \brief Sets the value of this three-dimensional vector to the vector difference of itself with the specified three-dimensional vector. + * \param vector The three-dimensional vector with which the vector difference should be computed. + * \return A reference to this three-dimensional vector. + */ + inline Vector3 &operator-=(const Vector3 &vector) + { + val_[0] -= vector[0]; + val_[1] -= vector[1]; + val_[2] -= vector[2]; + + return *this; + } + + inline Vector3 &operator=(const Vector3 &vector) + { + val_[0] = vector[0]; + val_[1] = vector[1]; + val_[2] = vector[2]; + + return *this; + } + + private: + float val_[3]; + }; + + + /** + * \relates Vector3 + * \brief Computes the scalar multiplication of the specified three-dimensional vector with the specified scalar value. + * \param scalar The scalar value with which the scalar multiplication should be computed. + * \param vector The three-dimensional vector with which the scalar multiplication should be computed. + * \return The scalar multiplication of the three-dimensional vector with the scalar value. + */ + inline Vector3 operator*(float scalar, const Vector3 &vector) + { + return Vector3(scalar * vector[0], scalar * vector[1], scalar * vector[2]); + } + + /** + * \relates Vector3 + * \brief Computes the cross product of the specified three-dimensional vectors. + * \param vector1 The first vector with which the cross product should be computed. + * \param vector2 The second vector with which the cross product should be computed. + * \return The cross product of the two specified vectors. + */ + inline Vector3 cross(const Vector3 &vector1, const Vector3 &vector2) + { + return Vector3(vector1[1] * vector2[2] - vector1[2] * vector2[1], vector1[2] * vector2[0] - vector1[0] * vector2[2], vector1[0] * vector2[1] - vector1[1] * vector2[0]); + } + + /** + * \relates Vector3 + * \brief Inserts the specified three-dimensional vector into the specified output stream. + * \param os The output stream into which the three-dimensional vector should be inserted. + * \param vector The three-dimensional vector which to insert into the output stream. + * \return A reference to the output stream. + */ + inline std::ostream &operator<<(std::ostream &os, const Vector3 &vector) + { + os << "(" << vector[0] << "," << vector[1] << "," << vector[2] << ")"; + + return os; + } + + /** + * \relates Vector3 + * \brief Computes the length of a specified three-dimensional vector. + * \param vector The three-dimensional vector whose length is to be computed. + * \return The length of the three-dimensional vector. + */ + inline float abs(const Vector3 &vector) + { + return std::sqrt(vector * vector); + } + + /** + * \relates Vector3 + * \brief Computes the squared length of a specified three-dimensional vector. + * \param vector The three-dimensional vector whose squared length is to be computed. + * \return The squared length of the three-dimensional vector. + */ + inline float absSq(const Vector3 &vector) + { + return vector * vector; + } + + /** + * \relates Vector3 + * \brief Computes the normalization of the specified three-dimensional vector. + * \param vector The three-dimensional vector whose normalization is to be computed. + * \return The normalization of the three-dimensional vector. + */ + inline Vector3 normalize(const Vector3 &vector) + { + return vector / abs(vector); + } +} + +#endif |