diff options
author | bptato <nincsnevem662@gmail.com> | 2024-06-27 21:50:31 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-06-28 21:26:33 +0200 |
commit | 8268ba2cf049be1865875e3e01305a500fa533e2 (patch) | |
tree | 7ce60624f9212e65dad0c1a2d168eb6ab7c03ec9 /src/layout | |
parent | f9734e2b3900781901bb5f268137bd9adbfc33ef (diff) | |
download | chawan-8268ba2cf049be1865875e3e01305a500fa533e2.tar.gz |
img, loader: add image resizing, misc fixes
* resize images with stb_image_resize * use tee for output handle redirection (redirectToFile blocks) * cache original image files * accept lseek in sandbox * misc stbi fixes For now, I just pulled in stb_image_resize v1. v2 is an extra 150K in size, not sure if it's worth the cost. (Either way, we can always switch later if needed, since the API is almost the same.) Next step: move sixel/kitty encoders to CGI, and cache their output in memory instead of the intermediate RGBA representation.
Diffstat (limited to 'src/layout')
-rw-r--r-- | src/layout/engine.nim | 30 | ||||
-rw-r--r-- | src/layout/renderdocument.nim | 4 |
2 files changed, 25 insertions, 9 deletions
diff --git a/src/layout/engine.nim b/src/layout/engine.nim index a764faad..3acc958e 100644 --- a/src/layout/engine.nim +++ b/src/layout/engine.nim @@ -1370,7 +1370,7 @@ proc addInlineBlock(ictx: var InlineContext; state: var InlineState; ictx.whitespacenum = 0 proc addInlineImage(ictx: var InlineContext; state: var InlineState; - bmp: Bitmap) = + bmp: Bitmap; padding: LayoutUnit) = let h = int(bmp.height).toLayoutUnit().ceilTo(ictx.cellHeight) let iastate = InlineAtomState( vertalign: state.fragment.computed{"vertical-align"}, @@ -1381,6 +1381,20 @@ proc addInlineImage(ictx: var InlineContext; state: var InlineState; bmp: bmp, size: size(w = int(bmp.width), h = h), #TODO overflow ) + let computed = state.fragment.computed + let lctx = ictx.lctx + if computed{"width"}.canpx(ictx.space.w): + let w = computed{"width"}.spx(lctx, ictx.space.w, computed, padding) + if not computed{"height"}.canpx(ictx.space.h): + # maintain aspect ratio + atom.size.h = atom.size.h div atom.size.w * w + atom.size.w = w + if computed{"height"}.canpx(ictx.space.h): + let h = computed{"height"}.spx(lctx, ictx.space.h, computed, padding) + if not computed{"width"}.canpx(ictx.space.w): + # maintain aspect ratio + atom.size.w = atom.size.w div atom.size.h * h + atom.size.h = h discard ictx.addAtom(state, iastate, atom) func calcLineHeight(computed: CSSComputedValues; lctx: LayoutContext): @@ -1421,7 +1435,7 @@ proc layoutInline(ictx: var InlineContext; fragment: InlineFragment) = case fragment.t of iftNewline: ictx.flushLine(state) of iftBox: ictx.addInlineBlock(state, fragment.box) - of iftBitmap: ictx.addInlineImage(state, fragment.bmp) + of iftBitmap: ictx.addInlineImage(state, fragment.bmp, padding.sum()) of iftText: ictx.layoutText(state, fragment.text) of iftParent: for child in fragment.children: @@ -2636,13 +2650,12 @@ proc pushInline(ctx: var InnerBlockContext; fragment: InlineFragment) = proc pushInlineText(ctx: var InnerBlockContext; computed: CSSComputedValues; styledNode: StyledNode; text: string) = - let box = InlineFragment( + ctx.pushInline(InlineFragment( t: iftText, computed: computed, node: styledNode, text: text - ) - ctx.pushInline(box) + )) proc pushInlineBlock(ctx: var InnerBlockContext; styledNode: StyledNode; computed: CSSComputedValues) = @@ -2788,13 +2801,12 @@ proc buildReplacement(ctx: var InnerBlockContext; child, parent: StyledNode; ctx.pushInlineText(computed, parent, child.content.s) of ContentImage: if child.content.bmp != nil: - let wrapper = InlineFragment( + ctx.pushInline(InlineFragment( t: iftBitmap, - computed: computed, + computed: parent.computed, node: parent, bmp: child.content.bmp - ) - ctx.pushInline(wrapper) + )) else: ctx.pushInlineText(computed, parent, "[img]") of ContentVideo: diff --git a/src/layout/renderdocument.nim b/src/layout/renderdocument.nim index e45b8af4..89afde32 100644 --- a/src/layout/renderdocument.nim +++ b/src/layout/renderdocument.nim @@ -218,6 +218,8 @@ type PosBitmap* = ref object x*: int y*: int + width*: int + height*: int bmp*: Bitmap RenderState = object @@ -379,6 +381,8 @@ proc renderInlineFragment(grid: var FlexibleGrid; state: var RenderState; state.images.add(PosBitmap( x: (offset.x div state.attrs.ppc).toInt, y: (offset.y div state.attrs.ppl).toInt, + width: atom.size.w.toInt, + height: atom.size.h.toInt, bmp: atom.bmp )) if fragment.computed{"position"} != PositionStatic: |