View Size Policies¶
This example demonstrates how requested view size policies resolve to real view sizes.
Preview¶
Run And Adapt¶
Commands below assume a Datoviz source checkout and start at the repository root. Use your configured build environment; Python routes additionally require local bindings.
| Route | Availability | Command or action |
|---|---|---|
| C | Canonical native source | just example-c features/view_size_policies (build and run), or rerun ./build/examples/c/features/view_size_policies |
| Python | Available; direct-engine adaptation | python3 -m examples.python.gallery.features.view_size_policies |
| Browser | Native only | demonstrates native window, framebuffer, and physical-size policies |
This example is approved as a starting point for user code and coding agents. Keep the object lifetimes and data shapes intact while adapting the data and styling.
What To Look For¶
Pass --policy pixel, host, reference, or physical to choose framebuffer pixels, host logical pixels, reference-DPI canvas pixels, or physical millimeters. The example prints the resolved canvas, host-logical, framebuffer, scale, and physical sizes, then renders a small point visual with position, color, and diameter_px arrays. This is useful when figures need reproducible screenshot dimensions across HiDPI monitors and different host toolkits.
Source¶
#!/usr/bin/env python3
"""Requested view size policies resolved into concrete view sizes."""
from __future__ import annotations
import argparse
import ctypes
import numpy as np
import datoviz as dvz
from examples.python.gallery import common as ex
POINT_COUNT = 5
DEFAULT_VIEW_KIND = dvz.DVZ_VIEW_WINDOW
def _policy_name(policy: int) -> str:
labels = {
dvz.DVZ_VIEW_SIZE_FRAMEBUFFER_PX: "pixel_exact",
dvz.DVZ_VIEW_SIZE_HOST_LOGICAL_PX: "host_logical_px",
dvz.DVZ_VIEW_SIZE_REFERENCE_PX: "reference_px",
dvz.DVZ_VIEW_SIZE_PHYSICAL_MM: "physical_mm",
}
return labels.get(policy, "unknown")
def _size_desc(policy: str):
if policy in {"pixel", "pixel_exact"}:
return dvz.dvz_view_size_desc_framebuffer_px(ex.WIDTH, ex.HEIGHT)
if policy in {"host", "host_logical", "host_logical_px"}:
return dvz.dvz_view_size_desc_host_logical_px(ex.WIDTH, ex.HEIGHT)
if policy in {"physical", "physical_mm"}:
return dvz.dvz_view_size_desc_physical_mm(338.7, 190.5, 96.0)
return dvz.dvz_view_size_desc_reference_px(float(ex.WIDTH), float(ex.HEIGHT), 96.0)
def _add_points(scene, panel) -> None:
positions = np.array(
[
[-0.70, -0.35, 0.0],
[-0.35, +0.26, 0.0],
[+0.00, +0.00, 0.0],
[+0.35, -0.24, 0.0],
[+0.70, +0.36, 0.0],
],
dtype=np.float32,
)
colors = ex.color_array(ex.WHITE, ex.CYAN, ex.YELLOW, ex.RED, ex.BLUE)
diameters = np.array([26.0, 34.0, 46.0, 58.0, 70.0], dtype=np.float32)
point = dvz.dvz_point(scene, 0)
if not point:
raise RuntimeError("dvz_point() failed")
if dvz.dvz_visual_set_data_many(
point,
{
"position": positions,
"color": colors,
"diameter_px": diameters,
},
) != 0:
raise RuntimeError("dvz_visual_set_data_many(point) failed")
ex.set_filled_point_style(point)
ex.add_visual(panel, point)
def _print_resolved(resolved) -> None:
print(f"policy: {_policy_name(resolved.requested_policy)}")
print(f"canvas_px: {resolved.canvas_width_px:.1f}x{resolved.canvas_height_px:.1f}")
print(f"host_logical_px: {resolved.host_logical_width}x{resolved.host_logical_height}")
print(f"framebuffer_px: {resolved.framebuffer_width}x{resolved.framebuffer_height}")
print(
"framebuffer_per_canvas_px: "
f"{resolved.framebuffer_per_canvas_px_x:.3f}x{resolved.framebuffer_per_canvas_px_y:.3f}"
)
if resolved.target_width_mm > 0.0 and resolved.target_height_mm > 0.0:
print(f"target_physical_mm: {resolved.target_width_mm:.1f}x{resolved.target_height_mm:.1f}")
def _build_scene(size, kind=DEFAULT_VIEW_KIND):
initial = dvz.dvz_view_size_resolve(ctypes.byref(size), kind)
width = int(initial.host_logical_width or ex.WIDTH)
height = int(initial.host_logical_height or ex.HEIGHT)
scene = dvz.dvz_scene()
if not scene:
raise RuntimeError("dvz_scene() failed")
figure = dvz.dvz_figure(scene, width, height, 0)
if not figure:
dvz.dvz_scene_destroy(scene)
raise RuntimeError("dvz_figure() failed")
panel = dvz.dvz_panel_full(figure)
if not panel:
dvz.dvz_scene_destroy(scene)
raise RuntimeError("dvz_panel_full() failed")
dvz.dvz_panel_set_background_color(panel, ex.BG)
_add_points(scene, panel)
return scene, figure, panel
def _view_desc(kind, size):
desc = dvz.dvz_view_desc(kind)
desc.size_policy = size.policy
desc.size_width = size.width
desc.size_height = size.height
desc.size_reference_dpi = size.reference_dpi
desc.size_requested_device_scale = size.requested_device_scale
desc.size_monitor_dpi_x_override = size.monitor_dpi_x_override
desc.size_monitor_dpi_y_override = size.monitor_dpi_y_override
desc.size_strict_framebuffer_size = size.strict_framebuffer_size
desc.title = b"View Size Policies"
return desc
def _run_view(policy: str = "reference", *, kind=DEFAULT_VIEW_KIND) -> tuple:
size = _size_desc(policy)
scene, figure, panel = _build_scene(size, kind)
app = dvz.dvz_app(scene)
if not app:
dvz.dvz_scene_destroy(scene)
raise RuntimeError("dvz_app() failed")
try:
desc = _view_desc(kind, size)
view = dvz.dvz_view(app, figure, ctypes.byref(desc))
if not view:
raise RuntimeError("dvz_view() failed")
if not dvz.dvz_view_panzoom(view, panel, None):
raise RuntimeError("dvz_view_panzoom() failed")
return scene, app, view, dvz.dvz_view_resolved_size(view)
except Exception:
dvz.dvz_app_destroy(app)
dvz.dvz_scene_destroy(scene)
raise
def _run_smoke(policy: str = "pixel"):
scene, app, view, resolved = _run_view(policy, kind=dvz.DVZ_VIEW_OFFSCREEN)
try:
status = dvz.dvz_view_render_once(view)
if status != dvz.DVZ_CANVAS_FRAME_READY:
raise RuntimeError("dvz_view_render_once() failed")
ex.capture_smoke(view)
if resolved.framebuffer_width <= 0 or resolved.framebuffer_height <= 0:
raise RuntimeError("resolved framebuffer size is empty")
return resolved
finally:
dvz.dvz_app_destroy(app)
dvz.dvz_scene_destroy(scene)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument(
"--policy",
choices=(
"pixel",
"pixel_exact",
"host",
"host_logical",
"host_logical_px",
"reference",
"physical",
"physical_mm",
),
default="reference",
)
parser.add_argument("--frames", type=int, default=0)
parser.add_argument("--smoke", action="store_true")
args = parser.parse_args()
if args.smoke or ex.SMOKE_MODE:
resolved = _run_smoke(args.policy)
_print_resolved(resolved)
return
scene, app, view, resolved = _run_view(args.policy, kind=dvz.DVZ_VIEW_WINDOW)
try:
_print_resolved(resolved)
if args.frames > 0 and not ex.SMOKE_MODE:
dvz.dvz_app_run(app, args.frames)
else:
ex.run_app(app, view)
finally:
dvz.dvz_app_destroy(app)
dvz.dvz_scene_destroy(scene)
if __name__ == "__main__":
main()
/*
* Copyright (c) 2021 Cyrille Rossant and contributors. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project root for details.
* SPDX-License-Identifier: MIT
*/
/* This example demonstrates how requested view size policies resolve to real view sizes.
*
* What to look for: pass --policy pixel, host, reference, or physical to choose framebuffer pixels,
* host logical pixels, reference-DPI canvas pixels, or physical millimeters. The example prints
* the resolved canvas, host-logical, framebuffer, scale, and physical sizes, then renders a small
* point visual with position, color, and diameter_px arrays. This is useful when figures need
* reproducible screenshot dimensions across HiDPI monitors and different host toolkits.
*
* Scenario: features_view_size_policies
* Style: features, graphite_cyan
*
* Build: just example-c features/view_size_policies
* Run: ./build/examples/c/features/view_size_policies --policy reference
* Smoke: ./build/examples/c/features/view_size_policies --policy pixel --frames 1
*/
/*************************************************************************************************/
/* Includes */
/*************************************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "datoviz/app.h"
#include "datoviz/scene.h"
#include "example_common.h"
#include "example_style.h"
/*************************************************************************************************/
/* Constants */
/*************************************************************************************************/
#define WIDTH EXAMPLE_WINDOW_WIDTH
#define HEIGHT EXAMPLE_WINDOW_HEIGHT
#define POINT_COUNT 5u
/*************************************************************************************************/
/* Helpers */
/*************************************************************************************************/
static const char* _policy_name(DvzViewSizePolicy policy)
{
switch (policy)
{
case DVZ_VIEW_SIZE_FRAMEBUFFER_PX:
return "pixel_exact";
case DVZ_VIEW_SIZE_HOST_LOGICAL_PX:
return "host_logical_px";
case DVZ_VIEW_SIZE_REFERENCE_PX:
return "reference_px";
case DVZ_VIEW_SIZE_PHYSICAL_MM:
return "physical_mm";
default:
return "unknown";
}
}
static DvzViewSizeDesc _parse_size_policy(int argc, char** argv)
{
const char* policy = "reference";
(void)example_arg_value(argc, argv, "--policy", &policy);
if (strcmp(policy, "pixel") == 0 || strcmp(policy, "pixel_exact") == 0)
return dvz_view_size_desc_framebuffer_px(WIDTH, HEIGHT);
if (strcmp(policy, "host") == 0 || strcmp(policy, "host_logical") == 0 ||
strcmp(policy, "host_logical_px") == 0)
return dvz_view_size_desc_host_logical_px(WIDTH, HEIGHT);
if (strcmp(policy, "physical") == 0 || strcmp(policy, "physical_mm") == 0)
return dvz_view_size_desc_physical_mm(338.7, 190.5, 96.0);
return dvz_view_size_desc_reference_px((double)WIDTH, (double)HEIGHT, 96.0);
}
static bool _parse_frame_count(int argc, char** argv, uint32_t* out)
{
if (out == NULL)
return false;
const char* value = NULL;
if (example_arg_value(argc, argv, "--frames", &value))
return example_parse_u32(value, out);
*out = example_frame_count_any(argc, argv);
return true;
}
static bool _add_points(DvzScene* scene, DvzPanel* panel)
{
vec3 positions[POINT_COUNT] = {
{-0.70f, -0.35f, 0.0f},
{-0.35f, +0.26f, 0.0f},
{+0.00f, +0.00f, 0.0f},
{+0.35f, -0.24f, 0.0f},
{+0.70f, +0.36f, 0.0f},
};
DvzColor colors[POINT_COUNT] = {
{245, 245, 245, 255},
{47, 197, 205, 255},
{250, 219, 82, 255},
{223, 84, 116, 255},
{110, 137, 241, 255},
};
float diameters[POINT_COUNT] = {26.0f, 34.0f, 46.0f, 58.0f, 70.0f};
DvzVisual* point = dvz_point(scene, 0);
if (point == NULL)
return false;
DvzVisualDataUpdate updates[] = {
{.attr_name = "position", .data = positions, .item_count = POINT_COUNT},
{.attr_name = "color", .data = colors, .item_count = POINT_COUNT},
{.attr_name = "diameter_px", .data = diameters, .item_count = POINT_COUNT},
};
if (dvz_visual_set_data_many(point, updates, DVZ_ARRAY_COUNT(updates)) != 0)
return false;
DvzPointStyleDesc style = dvz_point_style_desc();
style.stroke_width_px = 0.0f;
if (dvz_point_set_style(point, &style) != 0)
return false;
return dvz_panel_add_visual(panel, point, NULL) == 0;
}
static void _print_resolved(const DvzResolvedViewSize* resolved)
{
dvz_fprintf(stdout, "policy: %s\n", _policy_name(resolved->requested_policy));
dvz_fprintf(
stdout, "canvas_px: %.1fx%.1f\n", resolved->canvas_width_px, resolved->canvas_height_px);
dvz_fprintf(
stdout,
"host_logical_px: %ux%u\n", resolved->host_logical_width,
resolved->host_logical_height);
dvz_fprintf(
stdout,
"framebuffer_px: %ux%u\n", resolved->framebuffer_width,
resolved->framebuffer_height);
dvz_fprintf(
stdout,
"framebuffer_per_canvas_px: %.3fx%.3f\n", resolved->framebuffer_per_canvas_px_x,
resolved->framebuffer_per_canvas_px_y);
if (resolved->target_width_mm > 0.0 && resolved->target_height_mm > 0.0)
dvz_fprintf(
stdout,
"target_physical_mm: %.1fx%.1f\n", resolved->target_width_mm,
resolved->target_height_mm);
}
/*************************************************************************************************/
/* Main */
/*************************************************************************************************/
int main(int argc, char** argv)
{
int ret = 1;
DvzScene* scene = NULL;
DvzApp* app = NULL;
uint32_t frame_count = 0;
EXAMPLE_CHECK(_parse_frame_count(argc, argv, &frame_count), "invalid --frames value");
scene = dvz_scene();
EXAMPLE_CHECK(scene != NULL, "dvz_scene() failed");
DvzViewSizeDesc size = _parse_size_policy(argc, argv);
DvzResolvedViewSize initial = dvz_view_size_resolve(&size, DVZ_VIEW_WINDOW);
DvzFigure* figure = dvz_figure(
scene, initial.host_logical_width, initial.host_logical_height, 0);
DvzPanel* panel = figure != NULL ? dvz_panel_full(figure) : NULL;
EXAMPLE_CHECK(figure != NULL && panel != NULL, "failed to create figure/panel");
example_graphite_cyan_set_panel_background(panel);
EXAMPLE_CHECK(_add_points(scene, panel), "failed to add points");
app = dvz_app(scene);
EXAMPLE_CHECK(app != NULL, "dvz_app() failed (no GPU or display?)");
DvzViewDesc desc = dvz_view_desc(DVZ_VIEW_WINDOW);
desc.size_policy = size.policy;
desc.size_width = size.width;
desc.size_height = size.height;
desc.size_reference_dpi = size.reference_dpi;
desc.size_requested_device_scale = size.requested_device_scale;
desc.size_monitor_dpi_x_override = size.monitor_dpi_x_override;
desc.size_monitor_dpi_y_override = size.monitor_dpi_y_override;
desc.size_strict_framebuffer_size = size.strict_framebuffer_size;
desc.title = "View Size Policies";
DvzView* view = dvz_view(app, figure, &desc);
EXAMPLE_CHECK(view != NULL, "dvz_view() failed");
EXAMPLE_CHECK(dvz_view_panzoom(view, panel, NULL) != NULL, "dvz_view_panzoom() failed");
DvzResolvedViewSize resolved = dvz_view_resolved_size(view);
_print_resolved(&resolved);
dvz_app_run(app, frame_count);
ret = 0;
cleanup:
if (app != NULL)
dvz_app_destroy(app);
if (scene != NULL)
dvz_scene_destroy(scene);
return ret;
}
Example details
- ID:
features_view_size_policies - Category:
feature - Lane:
features - Status:
supported - Source:
examples/c/features/view_size_policies.c - Approved adaptation starter:
yes - Python source:
examples/python/gallery/features/view_size_policies.py - Python adaptation: Available; direct-engine adaptation
- Browser support: Native only
- Browser note: demonstrates native window, framebuffer, and physical-size policies
- Browser capability tags:
native-view,view-size-policy - Validation:
smoke+interaction
Tags
view-size, framebuffer, window
Data
| Field | Value |
|---|---|
kind |
synthetic |