Underlays are rasterised for the view's scale; DGN V7 strokes one pixel wide

A page shown small was drawn from its full-size raster and thin lines broke
up into dots. Once a zoom settles on another quarter-octave step, PDF, DWF
and DGN underlays are rasterised again near their size on screen (never
above the full-size raster), frames are requested until that happens, and
the adjusted-pixel memo is kept per raster size. V7 element weights no longer
widen strokes, matching V8 models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ramox81andClaude Opus 5.5 committed 2026-09-28 13:49:33 +03:00
1 parent cb7860e50e
commit 1cbe89ef62
8 files changed
+108 -19

No files matched your search

+4 -4
View File
@@ -198,9 +198,9 @@ fn read_run(run: &[&[u8]], colors: &[[u8; 3]]) -> Raw {
}
let symbology = uint16(e, 34).unwrap_or(0);
let color = colors[(symbology >> 8) as usize];
let weight = ((symbology & 0xf8) >> 3) as f64;
// Weights are screen pixels: a negative width asks for pixels.
let stroke = Some((color, -(weight * 2.0 + 1.0)));
// One pixel wide, as V8 models draw: the element weight is a
// lineweight, not shown while lineweights are off.
let stroke = Some((color, -1.0));
let fill = fill_index(e).map(|i| colors[i as usize]);
let int_pt = |i: usize| -> Option<[f64; 2]> { Some([int32(e, i)? as f64, int32(e, i + 4)? as f64]) };
match kind {
@@ -268,7 +268,7 @@ fn read_run(run: &[&[u8]], colors: &[[u8; 3]]) -> Raw {
// B-spline curve header: order, pole count.
let order = ((e.get(40).copied().unwrap_or(0) & 0x0f) + 2) as usize;
let poles = uint16(e, 42).unwrap_or(0) as usize;
spline = Some((order, poles, color, -(weight * 2.0 + 1.0)));
spline = Some((order, poles, color, -1.0));
knots.clear();
}
26 => {
+11 -9
View File
@@ -108,28 +108,30 @@ fn outline_texts(sheet: &mut Sheet) {
}
}
/// Longest side of a sheet's display raster, pixels.
const RASTER_SIDE: f64 = 3072.0;
/// Longest side of a sheet's full-size display raster, pixels.
pub const RASTER_SIDE: f64 = 3072.0;
/// The sheet drawn on a transparent background, straight alpha, rows from
/// the top, memoised.
pub fn display_raster(kind: UnderlayType, path: &str, item: &str) -> Option<Arc<PdfPage>> {
let key = (path.to_string(), item.to_string());
/// The sheet drawn on a transparent background with `side` pixels on its
/// longest side (at most [`RASTER_SIDE`]), straight alpha, rows from the
/// top, memoised per size.
pub fn display_raster(kind: UnderlayType, path: &str, item: &str, side: f64) -> Option<Arc<PdfPage>> {
let side = side.clamp(16.0, RASTER_SIDE).round();
let key = (path.to_string(), format!("{item}@{side}"));
if let Some(hit) = raster_cache().lock().unwrap_or_else(|e| e.into_inner()).get(&key) {
return hit.clone();
}
let value = sheet(kind, path, item).and_then(|s| rasterize(&s)).map(Arc::new);
let value = sheet(kind, path, item).and_then(|s| rasterize(&s, side)).map(Arc::new);
raster_cache().lock().unwrap_or_else(|e| e.into_inner()).insert(key, value.clone());
value
}
fn rasterize(sheet: &Sheet) -> Option<PdfPage> {
fn rasterize(sheet: &Sheet, side: f64) -> Option<PdfPage> {
let [x0, y0, x1, y1] = sheet.rect;
let (w, h) = (x1 - x0, y1 - y0);
if !(w > 0.0 && h > 0.0) {
return None;
}
let scale = RASTER_SIDE / w.max(h);
let scale = side / w.max(h);
let (pw, ph) = ((w * scale).ceil().max(1.0) as u32, (h * scale).ceil().max(1.0) as u32);
let mut pixmap = tiny_skia::Pixmap::new(pw, ph)?;
let to_px = |p: [f64; 2]| (((p[0] - x0) * scale) as f32, ((y1 - p[1]) * scale) as f32);