Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve aspect ratio of images #242

Merged
merged 19 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dillo-3.2.0 [Not released yet]
- Control the page overlap with the scroll_page_overlap option.
- Set focus_new_tab=NO and show_quit_dialog=NO by default.
- Fix GET requests over HTTPS via a proxy.
- Improve image resize logic to always try to preserve the aspect ratio.
Patches: Rodrigo Arias Mallo
+- Add primitive support for SVG using the nanosvg.h library.
- Add support for ch, rem, vw, vh, vmin and vmax CSS units.
Expand Down
64 changes: 35 additions & 29 deletions dw/image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Dillo Widget
*
* Copyright 2005-2007 Sebastian Geerken <[email protected]>
* Copyright 2024 Rodrigo Arias Mallo <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -19,6 +20,7 @@



//#define DEBUG_LEVEL 1
#include "image.hh"
#include "dlib/dlib.h"
#include "../lout/msg.h"
Expand Down Expand Up @@ -177,6 +179,13 @@ void Image::sizeRequestSimpl (core::Requisition *requisition)
{
DBG_OBJ_ENTER0 ("resize", 0, "sizeRequestImpl");

DEBUG_MSG(1, "-- Image::sizeRequestSimpl() begins\n");

DEBUG_MSG(1, "Image::sizeRequestImpl border: w=%d h=%d\n",
boxDiffWidth(), boxDiffHeight());

/* First set a naive size based on the image properties if given */

if (buffer) {
requisition->width = buffer->getRootWidth ();
requisition->ascent = buffer->getRootHeight ();
Expand All @@ -201,38 +210,18 @@ void Image::sizeRequestSimpl (core::Requisition *requisition)
requisition->ascent += boxOffsetY ();
requisition->descent += boxRestHeight ();

DEBUG_MSG(1, "Image: initial requisition (with border): w=%d, h=%d\n",
requisition->width, requisition->ascent + requisition->descent);

/* Then correct the size if needed, so it fits within the available space in
* the container widget. The correctRequisition() method will take into the
* account the preferred aspect ratio. */

correctRequisition (requisition, core::splitHeightPreserveDescent, true,
true);

if (buffer) {
// If one dimension is set, preserve the aspect ratio (without
// extraSpace/margin/border/padding). Notice that
// requisition->descent could have been changed in
// core::splitHeightPreserveDescent, so we do not make any
// assumtions here about it (and requisition->ascent).

// TODO Check again possible overflows. (Aren't buffer
// dimensions limited to 2^15?)

bool widthSpecified = getStyle()->width != core::style::LENGTH_AUTO ||
getStyle()->minWidth != core::style::LENGTH_AUTO ||
getStyle()->maxWidth != core::style::LENGTH_AUTO;
bool heightSpecified = getStyle()->height != core::style::LENGTH_AUTO ||
getStyle()->minHeight != core::style::LENGTH_AUTO ||
getStyle()->maxHeight != core::style::LENGTH_AUTO;

if (!widthSpecified && heightSpecified)
requisition->width =
(requisition->ascent + requisition->descent - boxDiffHeight ())
* buffer->getRootWidth () / buffer->getRootHeight ()
+ boxDiffWidth ();
else if (widthSpecified && !heightSpecified) {
requisition->ascent = (requisition->width + boxDiffWidth ())
* buffer->getRootHeight () / buffer->getRootWidth ()
+ boxOffsetY ();
requisition->descent = boxRestHeight ();
}
}
DEBUG_MSG(1, "Image: corrected requisition: w=%d, h=%d\n",
requisition->width, requisition->ascent + requisition->descent);

DBG_OBJ_MSGF ("resize", 1, "=> %d * (%d + %d)",
requisition->width, requisition->ascent, requisition->descent);
Expand Down Expand Up @@ -278,6 +267,13 @@ void Image::sizeAllocateImpl (core::Allocation *allocation)
allocation->x, allocation->y, allocation->width,
allocation->ascent, allocation->descent);

DEBUG_MSG(1, "Image::sizeAllocateImpl x=%d y=%d w=%d h=(%d + %d)\n",
allocation->x, allocation->y, allocation->width,
allocation->ascent, allocation->descent);

DEBUG_MSG(1, "Image::sizeAllocateImpl border: w=%d h=%d\n",
boxDiffWidth(), boxDiffHeight());


int newBufWidth = allocation->width - boxDiffWidth ();
int newBufHeight =
Expand All @@ -288,6 +284,9 @@ void Image::sizeAllocateImpl (core::Allocation *allocation)
(newBufWidth != bufWidth || newBufHeight != bufHeight)) {
DBG_OBJ_MSG ("resize", 1, "replacing buffer");

DEBUG_MSG(1, "Image::sizeAllocateImpl new buffer size: w=%d h=%d\n",
newBufWidth, newBufHeight);

core::Imgbuf *oldBuffer = buffer;
buffer = oldBuffer->getScaledBuf (newBufWidth, newBufHeight);
oldBuffer->unref ();
Expand All @@ -300,6 +299,10 @@ void Image::sizeAllocateImpl (core::Allocation *allocation)
DBG_OBJ_SET_NUM ("bufHeight", bufHeight);
}

DEBUG_MSG(1, "Image::sizeAllocateImpl x=%d y=%d w=%d h=(%d + %d)\n",
allocation->x, allocation->y, allocation->width,
allocation->ascent, allocation->descent);

DBG_OBJ_LEAVE ();
}

Expand Down Expand Up @@ -503,6 +506,9 @@ void Image::setBuffer (core::Imgbuf *buffer, bool resize)
}
queueResize (0, true);

if (bufWidth)
this->ratio = (float) bufWidth / (float) bufHeight;

DBG_OBJ_ASSOC_CHILD (this->buffer);
DBG_OBJ_SET_NUM ("bufWidth", bufWidth);
DBG_OBJ_SET_NUM ("bufHeight", bufHeight);
Expand Down
3 changes: 2 additions & 1 deletion dw/style.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define __DW_STYLE_HH__

#include <stdint.h>
#include <math.h>

#ifndef __INCLUDED_FROM_DW_CORE_HH__
# error Do not include this file directly, use "core.hh" instead.
Expand Down Expand Up @@ -471,7 +472,7 @@ inline double relLengthVal(Length l) { return (double)(l & ~3) / (1 << 18); }
* Use this instead of perLengthVal, when possible.
*/
inline int multiplyWithPerLength(int x, Length l) {
return x * perLengthVal_useThisOnlyForDebugging (l);
return (int) round((double) x * perLengthVal_useThisOnlyForDebugging (l));
}

/**
Expand Down
1 change: 1 addition & 0 deletions dw/ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ void ComplexButtonResource::correctRequisitionOfChild (Widget *child,
// the relief has to be considered.

if (style::isPerLength (child->getStyle()->width)) {
/* FIXME: Typo for getAvailWidth()? */
int availWidth = getEmbed()->getAvailHeight (false);
if (availWidth != -1) {
int baseWidth = misc::max (availWidth
Expand Down
Loading
Loading