forked from 1b-agent/opencadstudio-upstream
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:
1 parent
cb7860e50e
commit
1cbe89ef62
8 files changed
+108
-19
No files matched your search
@@ -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 => {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user