DPI / PPI Calculator — Kotlin source
Compute screen pixel density (PPI/DPI), dot pitch, physical dimensions, and aspect ratio from any resolution. Solve for PPI from a diagonal, or derive the diagonal from a known PPI - all in your browser.
This is the Kotlin implementation — the same logic the interactive tool runs, in a shareable, citable form.
// =============================================================================
// DpiPpi.kt — CosmoDev polyglot showcase port of the `dpi-ppi` tool
// -----------------------------------------------------------------------------
// Language : Kotlin (1.9, standard library only)
// Source: ported from src/lib/dpi-ppi.ts (the canonical, live TypeScript
// lib); mirrors src/tool-sources/dpi-ppi/{python.py,rust.rs}
// License : display source — part of CosmoDev's polyglot tool pages
// (dev.cosmolabs.org). Shown verbatim alongside the JS/TS/Go/Rust/
// Python ports and the other language ports.
// -----------------------------------------------------------------------------
// Display pixel-density math. Diagonal length in pixels, pixels-per-inch
// computed from a known physical diagonal, physical width/height/diagonal in
// both inches and millimeters, dot pitch in millimeters per pixel, and a
// reduced aspect ratio — all derived from a pixel resolution.
//
// Pure, deterministic, side-effect free. A zero divisor does not throw:
// Double division follows IEEE-754, so x / 0.0 yields ±Infinity and
// 0.0 / 0.0 yields NaN — callers should guard with isFinite() before
// display. (The Python port routes every division through a safeDiv wrapper
// only because Python raises ZeroDivisionError for float division.)
// =============================================================================
package com.cosmolabs.cosmodev
import kotlin.math.abs
import kotlin.math.sqrt
/** Display pixel-density math. */
object DpiPpi {
/** Fixed conversion factor between inches and millimeters. */
private const val MM_PER_INCH = 25.4
/** Pixels-per-inch result. */
data class Ppi(val ppi: Double)
/** Physical dimensions of a display, in inches and millimeters. */
data class PhysicalSize(
val widthIn: Double,
val heightIn: Double,
val diagonalIn: Double,
val widthMm: Double,
val heightMm: Double,
)
/**
* Diagonal length in pixels: √(w² + h²).
* The sign of the inputs is irrelevant because both terms are squared.
*/
fun diagonalPixels(w: Double, h: Double): Double = sqrt(w * w + h * h)
/** Pixels per inch, given a resolution and a known physical diagonal in inches. */
fun computePpi(w: Double, h: Double, diagonalInches: Double): Ppi =
Ppi(diagonalPixels(w, h) / diagonalInches)
/**
* Derive inches and millimeters from a resolution and a ppi. The diagonal
* is recomputed from the derived inch dimensions so it stays consistent
* with the width/height values.
*/
fun physicalSize(w: Double, h: Double, ppi: Double): PhysicalSize {
val widthIn = w / ppi
val heightIn = h / ppi
return PhysicalSize(
widthIn = widthIn,
heightIn = heightIn,
diagonalIn = diagonalPixels(widthIn, heightIn),
widthMm = widthIn * MM_PER_INCH,
heightMm = heightIn * MM_PER_INCH,
)
}
/** Dot pitch (pixel size) in millimeters per pixel: 25.4 / ppi. */
fun dotPitch(ppi: Double): Double = MM_PER_INCH / ppi
/**
* Integer greatest-common-divisor via Euclid's algorithm, used to reduce
* aspect ratios. Inputs are truncated toward zero (Double.toLong()) and
* taken in absolute value first, so the sign and fractional part of the
* inputs never matter.
*/
private fun gcd(a: Double, b: Double): Long {
var x = abs(a.toLong())
var y = abs(b.toLong())
while (y != 0L) {
val t = y
y = x % y
x = t
}
return x
}
/**
* Reduced aspect ratio as "w:h" (e.g. "16:9"). Returns "-" when either
* side is not a positive number (this also covers NaN, since every
* comparison with NaN is false).
*/
fun aspectRatio(w: Double, h: Double): String {
if (!(w > 0) || !(h > 0)) return "-"
val g = gcd(w, h)
if (g == 0L) return "-"
return "${w.toLong() / g}:${h.toLong() / g}"
}
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →