Open stanio opened 1 year ago
I have a sample Bibata-Modern-Ice-Windows-v2.0.4-stanio-1.zip
package I've compiled manually to what would be the expected result, attached to https://github.com/ful1e5/Bibata_Cursor/issues/116#issuecomment-1731767032:
Regular | Large | Extra-Large |
---|---|---|
@stanio Thank you for reporting this. I will look into it soon.
A side note: Given the original bitmaps map to "Extra-Large" (fully occupying the canvas), I'm producing the "Large" and "Regular" variants by expanding the original canvas (filling with space to the right and bottom) with ¼ and ½ from the original size respectively. Then I'm scaling to the same target resolutions:
I'm pointing this out as it could be achieved by manipulating the source SVG viewBox
:
Extra-Large | Large | Regular |
---|---|---|
width="#" height="#" viewBox="0 0 256 256" |
width="#" height="#" viewBox="0 0 320 320" |
width="#" height="#" viewBox="0 0 384 384" |
Updating the width
and height
to each target resolution then allows rendering the SVG directly at the target resolution, avoiding whatever (minimal) blur may appear from downscaling a single "master" bitmap. This is just a general suggestion not necessary for the purpose of solving the original issue.
Here's a PoC I've come up with: wincur.zip (Java 11+, source included in the package)
alias wincur="java -jar <path-to>/wincur.zip"
alias winani="java -cp <path-to>/wincur.zip io.github.stanio.windows.AnimatedCursor"
Sample usage
Using the rendered source bitmaps (256×256), create Extra-Large, Large, and Regular variants each including five resolutions (32×32, 48×48, 64×64, 96×96, 128×128) of a static cursor:
wincur pin.png -h 42,15 -r 32 -r 48 -r 64 -r 96 -r 128 -o Pin_xl.cur
wincur pin.png -h 42,15 -s 1.25 -r 32 -r 48 -r 64 -r 96 -r 128 -o Pin_l.cur
wincur pin.png -h 42,15 -s 1.5 -r 32 -r 48 -r 64 -r 96 -r 128 -o Pin.cur
-h
specifies the hotspot. It is automatically adjusted for the target resolution and extra view-box sizing (-s
). I've included possibility for generating cursors with multiple bitmap sources for the different resolutions, also.
Creating an animated cursor is a two-step operation:
# Create cursor files for each frame
for f in left_ptr_watch-*.png; do wincur $f -h 42,15 -r 32 -r 48 -r 64 || break; done
# Create the animated cursor (left_ptr_watch.ani)
winani -j 4 left_ptr_watch-*.cur
-j
specifies the frame rate in jiffies (1/60 of a second). I've made it use 3 jiffies (5 ms, 20 fps) by default.
Whomever it may benefit:
@stanio Launched Bibata, a web app at https://bibata.live/ for personalizing cursor color and size in browsers.
Thanks for your patience and support. Closing this issue.
Trying out bibata.live I find virtually nothing has changed related to the original issue:
There's no possibility to download higher resolution (>= 32) of a "Regular" or "Large" size schemes
Every dimension >= 32 produces just an "Extra-Large" scheme cursors:
Regular | Large | bibata.live (Extra-Large) |
|
---|---|---|---|
48×48 |
In this regard, I find the following statement on Windows cursors support currently on the bibata.live site largely misleading:
Bibata Studio craft Windows cursors with seamless HiDPI support...
Bibata packages currently provide very basic (standard-resolution) Windows support.
[For archival purposes] Here's a streamlined approach to produce all necessary bitmaps. The following table lists all bitmap sizes to be rendered (or downsampled from a single master bitmap):
size | Regular × ²⁄₃ |
Large × ⁴⁄₅ |
Extra-Large × 1 |
---|---|---|---|
32 | 21.333 → 22 | 25.6 → 26 | 32 |
48 | 32 | 38.4 → 39 | 48 |
64 | 42.666 → 43 | 51.2 → 52 | 64 |
96 | 64 | 76.8 → 77 | 96 |
128 | 85.333 → 86 | 102.4 → 103 | 128 |
The leftmost column specifies the final bitmap sizes included in a cursor. Each of these is produced by expanding the corresponding rendered (scaled) bitmap size, filling in with space (no resampling) to the bottom right of the target canvas, as necessary.
The relative factors ²⁄₃ (Regular) and ⁴⁄₅ (Large) are derived from my https://github.com/ful1e5/Bibata_Cursor/issues/149#issuecomment-1741739558 approach which is the other way around: expand the master canvas (with space) by ¹⁄₂ (Regular) or ¹⁄₄ (Large), then scale to the target size.
At the end, multi-resolution cursors should be compiled.
In case others stumble upon this issue, here are Windows packages I've compiled for my use: stanio/Bibata_Cursor.
Here is a single cursor sample (Unavailable / circle) – three files:
Unavailable.cur
Unavailable_l.cur
Unavailable_xl.cur
Each of the three contains the same resolutions (canvas sizes): 32x32, 48x48, 64x64, 96x96, 128x128. However Regular 32x32, Large 32x32, and Extra-Large 32x32 are different bitmaps. As given in a table previously (https://github.com/ful1e5/Bibata_Cursor/issues/149#issuecomment-1945460036) – the actual used size on a 32x32 Regular canvas is ~22x22, for Large it is ~26x26, while Extra-Large occupies the full canvas.
See how it looks in an editor:
Regular | Large | Extra-Large |
---|---|---|
@stanio Thanks for your help with the issue. My main challenge now is incorporating multi-dimensional animated cursor frames into a single file.
I discovered bugs in the clickgen code and realized additional features are needed to package Windows cursors based on your suggestions. I plan to look into this further when time allows.
Meanwhile, I'm reverting the previous patch that removed rendering inside the 32 canvas (https://github.com/ful1e5/clickgen/commit/aa9ea8a1102026d656c06ad28a40e9d781d9e124)
Regarding .ani
files, I couldn't find information about supporting multiple dimension cursors. If you have insights on this, your contributions to the clickgen/writer/windows module would be appreciated.
I plan to look into this further when time allows.
Fair enough.
Regarding
.ani
files, I couldn't find information about supporting multiple dimension cursors. If you have insights on this, your contributions to the clickgen/writer/windows module would be appreciated.
I wouldn't be able to help with a source contribution as I don't have Python experience, but given you already have basic .ani
support implemented – the ANI
file is just a sequence of CUR
frames. Each CUR
/frame stores its resolutions individually (as a static cursor). That is, the ANI
file doesn't care about the resolutions.
I have saved the following general documentation references in my Java implementation:
but again – you should have that implemented already. If you have implemented multiple resolutions in the static CUR
cursors – that's all you need for multi-resolution ANI
cursors as well.
I see v2.0.7 already includes multi-resolution cursors – looks promising!
Here are a couple of observations from me:
The static cursors store the resolution variants in ascending order, while the standard cursors have them in reverse (compare with screenshots I've posted previously to this issue):
I don't know if this could be a problem;
The animated cursors have the resolutions in descending order but they appear to mix bitmaps from different relative sizes (like "Small", "Regular", "Large", "Extra-Large") in a single resolution:
Frame 1 | Frame 2 | Frame 3 | Frame 4 |
---|---|---|---|
It is somewhat inconsistent. The 96x96 resolution of the Regular variant contains 4 54 (216) frames, the 64x64 and 48x48 resolutions contain 2 54 (108) frames, and the 32x32 resolution contains 5 * 54 (324) frames. The Extra-Large variant contains just a 96x96 resolution with just 54 frames.
It is somewhat inconsistent.
This is likely my editor software trying to make sense of something broken in the file format. An ANI file has a fixed number of frames. The individual frames (CUR) may unconventionally contain a varying number of resolutions, but that's likely to confuse any software trying to interpret the animation.
This is likely my editor software trying to make sense of something broken in the file format.
From "Bibata-Modern-Ice-Windows-v2.0.7.zip", I have extracted the individual frames (looking up and saving icon
chunks) of Work.ani
as separate CUR
files, and I'm seeing the "Regular" and "Large" frames contain multiple entries of the same resolution:
Each entry of the same resolution appears to be a slightly larger canvas-size version of the previous one. As noted before, the "Extra-Large" frames appear to have just a (single) 96×96 resolution.
I'm seeing the "Regular" and "Large" frames contain multiple entries of the same resolution... Each entry of the same resolution appears to be a slightly larger canvas-size version of the previous one.
As far as I've observed, the effect is Windows picks the last entry of the same resolution which happens to be the largest canvas painting, and animated cursors from all of the "Regular", "Large", and "Extra-Large" variants are displayed just as "Extra-Large".
(Follow-up to #116 and #119.)
To adapt for hi-dpi (different resolution) screens the standard Windows cursors provide multiple resolutions for each cursor: 32×32, 48×48, 64×64, 96×96, and 128×128, packaged inside the individual cursor files.
The difference between the "Regular", "Large", and "Extra-Large" schemes is the relative amount of space the cursor shape occupies on the canvas, regardless of the resolution:
(The thin red rulers in the middle and the X spots are not part of the cursor images.)
Likely to conserve memory space the standard animated cursors provide just 32×32, 48×48, and 64×64 resolutions:
Compared with the current Bibata packages – they provide just a single resolution (per scheme):
One may notice the "Large" and "Extra-Large" schemes provide different resolutions for what is essentially a single scheme (I deem): "Extra-Large". "Small" and "Regular" map more closely to "Regular" and "Large".
Ultimately this causes dynamic upscale resampling and blurry cursors on hi-dpi screens. The individual Bibata cursors for Windows should provide multiple resolutions as with the standard Windows cursors.
I guess this is dependent on clickgen supporting it, also.