diff options
author | bptato <nincsnevem662@gmail.com> | 2024-03-03 23:10:44 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-03-03 23:18:25 +0100 |
commit | 15d5ad451bdc456e80e7468a76fb2eac6feb4a4e (patch) | |
tree | 941481cc2795e1dd191b928737a323362e298b16 /src/utils | |
parent | fb04a7e96ff68b4516ea483ca4fbe9c4976bb7d2 (diff) | |
download | chawan-15d5ad451bdc456e80e7468a76fb2eac6feb4a4e.tar.gz |
strwidth, renderdocument: small refactoring
* put attrs pointer in state * simplify width() * use unsigned int as ptint to avoid UB
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/proptable.nim | 14 | ||||
-rw-r--r-- | src/utils/strwidth.nim | 57 |
2 files changed, 26 insertions, 45 deletions
diff --git a/src/utils/proptable.nim b/src/utils/proptable.nim index a34459a8..0087dd80 100644 --- a/src/utils/proptable.nim +++ b/src/utils/proptable.nim @@ -1,12 +1,10 @@ -import std/unicode - # Lookup tables for characters on the BMP. This "only" takes up 8k of space # per table, as opposed to the 135k that storing all characters would require. # The downside is obviously that we need a binary search fallback for non-bmp. # We do not store a lookup table of ambiguous ranges, either. type - ptint* = int32 + ptint* = uint32 PropertyTable* = array[0x10000 div (sizeof(ptint) * 8), ptint] RangeMap* = openArray[(uint32, uint32)] @@ -32,9 +30,9 @@ func makePropertyTable*(ranges: RangeMap, skip: RangeMap = @[]): PropertyTable = inc ucs {.push boundChecks:off.} -func contains*(props: PropertyTable, r: Rune): bool = - let u = ptint(r) - let i = u div (sizeof(ptint) * 8) - let m = u mod (sizeof(ptint) * 8) - return (props[i] and (1 shl m)) != 0 +func contains*(props: PropertyTable, u: ptint): bool {.inline.} = + const isz = sizeof(ptint) * 8 + let i = u div isz + let m = u mod isz + return (props[i] and (1u32 shl m)) != 0 {.pop.} diff --git a/src/utils/strwidth.nim b/src/utils/strwidth.nim index 5ce2ba52..9cb115cc 100644 --- a/src/utils/strwidth.nim +++ b/src/utils/strwidth.nim @@ -7,48 +7,31 @@ import utils/map include res/map/charwidth_gen -func isDoubleWidthHigh(r: Rune): bool = - return DoubleWidthRanges.isInRange(uint32(r)) - -func isDoubleWidthAmbiguousHigh(r: Rune): bool = - # binary search in table of non-spacing characters - if DoubleWidthAmbiguousRanges.isInRange(uint32(r)): - return true - return r.isDoubleWidthHigh() - -func isCombining(r: Rune): bool = - return Combining.isInRange(uint32(r)) - # One of the few global variables in the code. Honestly, it should not exist. -var is_cjk_ambiguous = false +var isCJKAmbiguous = false proc set_cjk_ambiguous*(b: bool) = - is_cjk_ambiguous = b + isCJKAmbiguous = b # Warning: this shouldn't be called without normalization. -# We could make this function more efficient in edge cases, but it's already -# too complex for my taste. func width*(r: Rune): int = - {.cast(noSideEffect).}: - let u = uint32(r) - if u <= 0xFFFF: - if r in CombiningTable: - return 0 - if not is_cjk_ambiguous: - if r in DoubleWidthTable: - return 2 - else: - if r in DoubleWidthTable or DoubleWidthAmbiguousRanges.isInRange(u): - return 2 - else: - if r.isCombining(): - return 0 - if not is_cjk_ambiguous: - if r.isDoubleWidthHigh(): - return 2 - else: - if r.isDoubleWidthAmbiguousHigh(): - return 2 - return 1 + let u = uint32(r) + if u <= 0xFFFF: # fast path for BMP + if u in CombiningTable: + return 0 + if u in DoubleWidthTable: + return 2 + {.cast(noSideEffect).}: + if isCJKAmbiguous and DoubleWidthAmbiguousRanges.isInRange(u): + return 2 + else: + if Combining.isInRange(u): + return 0 + if DoubleWidthRanges.isInRange(u): + return 2 + {.cast(noSideEffect).}: + if isCJKAmbiguous and DoubleWidthAmbiguousRanges.isInRange(u): + return 2 + return 1 # Width, but also works with tabs. # Needs the column width of the text so far. |