gpt4 book ai didi

c - 在 Swift 3 中读取 TrueType 'cmap' 格式 4 子表

转载 作者:太空宇宙 更新时间:2023-11-04 03:26:23 25 4
gpt4 key购买 nike

如何在 Swift 中编写以下 C 代码?

glyphIndex = *(&idRangeOffset[i] + idRangeOffset[i] / 2 + (c - startCode[i]))

我正在尝试使用一个简单的小型二进制数据读取器来读取 Format 4 TrueType 字符映射表。在涉及指针操作之前,一切都很好,因为在 C 中工作时我几乎无法制作指针的头部或尾部,更不用说那些伪装成带有 Unsafe 前缀的指针了。

我已经尝试了很多东西,但似乎没有什么是正确的。我想我只是不确定如何在 Swift 中使用指针“地址”。

例如,这里有一个更完整的关于我在哪里的想法:

// The following variables are all [UInt16]:
// - startCodes
// - endCodes
// - idDeltas
// - idRangeOffsets

var gids = [Int]()

// Iterate segments, skipping the last character code (0xFFFF)
for i in 0 ..< segCount - 1 {

let start = startCodes[i]
let end = endCodes[i]
let delta = idDeltas[i]
let rangeOffset = idRangeOffsets[i]
let charRange = start ..< (end + 1)

if rangeOffset == 0 {
gids.append(contentsOf: charRange.map { charCode in
return (charCode + delta) & 0xFFFF
})
}
else {
for charCode in charRange {
// ???
}
}
}

在上面的代码中,您会注意到 ???。这是我使用上面提到的奇怪的 C-pointer-address-pointer-huh 技巧检索字形索引的地方。问题是,我就是想不通。替换我真正理解的变量,这是我得到的:

for charCode in charRange {
Not too sure about this Actual value of idRangeOffset[i]
| |
v v
glyphIndex = *(&idRangeOffset[i] + rangeOffset / 2 + (charCode - start))
^
|
Or this
}

是否有任何 Swift 3 指针大师可以引导我走上启蒙之路?任何帮助将不胜感激!

最佳答案

如果我将你的伪 C 代码逐字翻译成 Swift,它会是这样的:

//"May not work" example, do no use this
glyphIndex = withUnsafePointer(to: &idRangeOffset[i]) {idRangeOffsetPointer in
//In some cases `idRangeOffsetPointer` can work as `&idRangeOffset[i]` in C...
(idRangeOffsetPointer + Int(rangeOffset) / 2 + Int(charCode - start)).pointee
//To make pointer operation in Swift, all integers need to be `Int`,
//And to match the C-rule of integer operation, you need to cast each portion to `Int` before adding operation
//The equivalent to C's dereferencing operator `*` in Swift is `pointee` property
}

但由于 Swift 的 inout 参数的copy-in/copy-out 语义,这可能无法按预期工作。 Swift 可能会创建一个包含单个元素 idRangeOffset[i] 的时间区域,并将其地址传递给 idRangeOffsetPointer,因此指针操作的结果可能指向某处靠近颞区,完全没用。

如果您想从指针操作中获得有意义的结果,您可能需要在保证数组的所有元素都放置在连续区域中的上下文中工作。

你还应该知道 C 语句:

glyphIndex = *(&idRangeOffset[i] + idRangeOffset[i] / 2 + (c - startCode[i]))

基于这样的事实,即整个 idRangeOffsetglyphIdArray 被放置在一个连续的区域中,没有任何间隙或填充。 (我假设您对格式 4 很了解。)

因此,如果您的 idRangeOffset 仅包含 segCount 元素,则以下代码将不起作用。

//"Should work" in a certain condition
glyphIndex = idRangeOffset.withUnsafeBufferPointer{idRangeOffsetBufferPointer in
let idRangeOffsetPointer = idRangeOffsetBufferPointer.baseAddress! + i
//`idRangeOffsetPointer` is equivalent to `&idRangeOffset[i]` in C inside this closure
return (idRangeOffsetPointer + Int(rangeOffset) / 2 + Int(charCode - start)).pointee
}

但考虑到 C 中的指针和数组语义,上面的代码等同于:

glyphIndex = idRangeOffset[i + Int(rangeOffset) / 2 + Int(charCode - start)]

//`*(&arr[i] + n)` is equivalent to `arr[i + n]` in C

我再说一遍,数组 idRangeOffset 需要包含 idRangeOffset 和 glyphIdArray 的全部内容。

关于c - 在 Swift 3 中读取 TrueType 'cmap' 格式 4 子表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40867409/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com