⚡ A tiny, zero-dependency aspect-ratio scaling utility for Java.
FastProportion is a lightweight math library for pixel-accurate layout calculations. It computes contain, cover, fit-horizontal, and fit-vertical scaling modes, returning the resulting viewport coordinates as a float[]. Designed as the mathematical foundation for responsive FastJava UIs.
Watch the Demo
- Why FastProportion?
- Quick Start
- Features
- API Quick Reference
- Installation
- Documentation
- Platform Support
- License
- Related Projects
Standard Java layout approaches — GridBagLayout, manual Math.min/Math.max scaling inline in paintComponent, or ad-hoc OOP abstractions — tend to tangle the scaling math with the rendering code. This makes animations and mode transitions brittle and hard to test in isolation.
FastProportion separates the math cleanly from the UI:
- Pure float pipeline: All calculations use 32-bit floats from input to output, keeping the internal math clean before the final draw cast.
- Minimal and focused: The library does one thing — compute scaled bounding boxes — with no dependencies and no hidden state.
- Easy to interpolate: Because
compute()returns plainfloat[]values, animating between two modes is a straightforward lerp with no additional abstraction required.
Note:
compute()allocates a smallfloat[4]array on each call. This is negligible for typical UI use, but if you are calling it in a tight inner loop at very high frequency, caching the result is recommended.
import fastproportion.Proportion;
import fastproportion.ProportionMode;
public class Example {
public static void main(String[] args) {
// Container: 500×500, Content: 1920×1080
Proportion p = new Proportion(500, 500, 1920, 1080);
// Calculate the bounding box for CONTAIN mode
float[] bounds = p.compute(ProportionMode.CONTAIN);
float x = bounds[0];
float y = bounds[1];
float w = bounds[2];
float h = bounds[3];
System.out.printf("Draw at: x=%.1f, y=%.1f, w=%.1f, h=%.1f%n", x, y, w, h);
}
}- Accurate scaling: Four standard modes — contain, cover, fit-horizontal, fit-vertical — computed with a strictly 32-bit float pipeline.
- Seamless transitions: Return values are plain floats, easy to lerp for animated mode switches.
- Small and focused: No dependencies, no reflection, no configuration.
- Framework-agnostic: Works with Java2D, OpenGL, or any custom rendering pipeline.
FastProportion provides two compute methods:
- Standard API (allocates a new
float[4])
float[] result = p.compute(ProportionMode.CONTAIN);- Zero‑Allocation API (recommended for real‑time UIs)
float[] out = new float[4];
p.compute(ProportionMode.CONTAIN, out);The zero‑allocation version avoids creating new arrays and is ideal for:
- animation systems
- layout engines
- high‑FPS rendering
- GPU upload pipelines
- FastUI / FastGrid / FastOverlay
Using the zero‑allocation API:
| Benchmark Code | Average Time (ns/op) |
|---|---|
computeContainZeroAllocation |
≈ 6.5 ns/op |
computeCoverZeroAllocation |
≈ 6.4 ns/op |
This corresponds to:
👉 ~150 million compute() calls per second
Measured with:
- JDK 25
- JMH 1.37
- 3 forks × 10 iterations
- AverageTime mode (ns/op)
- Blackhole compiler mode
FastProportion is effectively free in any real‑time rendering pipeline.
@Benchmark
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
public float computeContainZeroAllocation() {
proportion.compute(ProportionMode.CONTAIN, out);
return out[0]; // force JIT to keep the computation
}This measures the pure math path without allocations, matching real‑world usage in FastUI and FastGrid.
| Method | Description |
|---|---|
new Proportion(w, h, cw, ch) |
Creates a scaling context with container dimensions (w, h) and content dimensions (cw, ch). Position defaults to (0, 0); set p.x and p.y before calling compute() if needed. |
compute(ProportionMode mode) |
Returns float[] { scaledX, scaledY, scaledWidth, scaledHeight } for the given mode. |
| Mode | Behaviour |
|---|---|
CONTAIN |
Scale to fit entirely within the container, preserving aspect ratio. Letterboxed if needed. |
COVER |
Scale to fill the container entirely, preserving aspect ratio. Content may be clipped. |
FIT_HORIZONTAL |
Scale so the content width matches the container width exactly. |
FIT_VERTICAL |
Scale so the content height matches the container height exactly. |
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.andrestubbe</groupId>
<artifactId>fastproportion</artifactId>
<version>v0.1.0</version>
</dependency>
</dependencies>repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.andrestubbe:fastproportion:v0.1.0'
}- PHILOSOPHY.md — Design rationale and goals.
- ROADMAP.md — Planned features and milestones.
| Platform | Status |
|---|---|
| Windows | ✅ Supported |
| Linux | ✅ Supported |
| macOS | ✅ Supported |
MIT — see LICENSE for details.
- FastAnimation — Timeline-based animation engine
- FastTween — Pool-based tweening
- FastTheme — Native window styling
- FastUI — Java UI framework
- FastCore — JNI loader and utilities
Part of the FastJava ecosystem.
