[ghex/gtk4-port: 65/91] Move cpl calculation to the layout manager.
- From: Logan Rathbone <larathbone src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ghex/gtk4-port: 65/91] Move cpl calculation to the layout manager.
- Date: Thu, 12 Aug 2021 23:35:11 +0000 (UTC)
commit 9113f893559b740b9594af2a83d75f0adcc8e57c
Author: Logan Rathbone <poprocks gmail com>
Date: Thu Jan 28 01:01:39 2021 -0500
Move cpl calculation to the layout manager.
The hex/ascii ratio in the widget needs optimization with longer byte
groups, but I think this is a step in the right direction.
src/gtkhex-layout-manager.c | 73 ++++++++++++++++++++++++------
src/gtkhex-layout-manager.h | 9 ++++
src/gtkhex.c | 105 ++++++++++++++------------------------------
src/gtkhex.h | 9 +---
4 files changed, 102 insertions(+), 94 deletions(-)
---
diff --git a/src/gtkhex-layout-manager.c b/src/gtkhex-layout-manager.c
index fcb18a1e..f48bb2b7 100644
--- a/src/gtkhex-layout-manager.c
+++ b/src/gtkhex-layout-manager.c
@@ -36,9 +36,10 @@ struct _GtkHexLayout {
GtkWidget *ascii;
guint char_width;
+ guint group_type;
- int hex_width;
- int ascii_width;
+ int cpl;
+ int hex_cpl;
};
G_DEFINE_TYPE (GtkHexLayout, gtk_hex_layout, GTK_TYPE_LAYOUT_MANAGER)
@@ -51,7 +52,6 @@ struct _GtkHexLayoutChild {
enum {
PROP_CHILD_COLUMN = 1,
-
N_CHILD_PROPERTIES
};
@@ -211,6 +211,27 @@ gtk_hex_layout_measure (GtkLayoutManager *layout_manager,
*natural = natural_size;
}
+/* Helper */
+static void
+get_cpl_from_ascii_width (GtkHexLayout *self, int width)
+{
+ int hex_cpl, ascii_cpl;
+
+ g_debug ("%s: GROUP_TYPE: %u", __func__, self->group_type);
+
+ /* Hex characters per line is a simple calculation: */
+
+ ascii_cpl = width / self->char_width;
+ while (ascii_cpl % self->group_type != 0)
+ --ascii_cpl;
+
+ hex_cpl = ascii_cpl * 2;
+ hex_cpl += ascii_cpl / self->group_type;
+
+ self->hex_cpl = hex_cpl;
+ self->cpl = ascii_cpl;
+}
+
static void
gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
GtkWidget *widget,
@@ -240,12 +261,12 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
if (! gtk_widget_should_layout (child))
continue;
- /* Get preferred size of the child widget
- */
+ /* Get preferred size of the child widget */
+
gtk_widget_get_preferred_size (child, &child_req, NULL);
- /* Setup allocation depending on what column we're in.
- */
+ /* Setup allocation depending on what column we're in. */
+
child_info =
GTK_HEX_LAYOUT_CHILD(gtk_layout_manager_get_layout_child (layout_manager,
child));
@@ -268,7 +289,8 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
scr_alloc.height = height;
break;
default:
- g_error ("%s: Programming error. The requested column is invalid.",
+ g_error ("%s: Programming error. "
+ "The requested column is invalid.",
__func__);
break;
}
@@ -283,12 +305,12 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
if (! gtk_widget_should_layout (child))
continue;
- /* Get preferred size of the child widget
- */
+ /* Get preferred size of the child widget */
+
gtk_widget_get_preferred_size (child, &child_req, NULL);
- /* Setup allocation depending on what column we're in.
- */
+ /* Setup allocation depending on what column we're in. */
+
child_info =
GTK_HEX_LAYOUT_CHILD(gtk_layout_manager_get_layout_child
(layout_manager, child));
@@ -320,6 +342,9 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
* HEX_RATIO;
}
tmp_alloc = asc_alloc;
+
+ get_cpl_from_ascii_width (self, asc_alloc.width);
+
break;
case SCROLLBAR_COLUMN:
@@ -373,9 +398,9 @@ gtk_hex_layout_class_init (GtkHexLayoutClass *klass)
static void
gtk_hex_layout_init (GtkHexLayout *self)
{
- g_debug ("%s: TEST - SETTING A DEFAULT MINIMUM CHAR-WIDTH",
- __func__);
+ /* FIXME - dumb test initial default */
self->char_width = 20;
+ self->group_type = GROUP_BYTE;
}
/* GtkHexLayout - Public Methods */
@@ -394,6 +419,26 @@ gtk_hex_layout_set_char_width (GtkHexLayout *layout, guint width)
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER(layout));
}
+void
+gtk_hex_layout_set_group_type (GtkHexLayout *layout, guint group_type)
+{
+ layout->group_type = group_type;
+
+ gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER(layout));
+}
+
+int
+gtk_hex_layout_get_cpl (GtkHexLayout *layout)
+{
+ return layout->cpl;
+}
+
+int
+gtk_hex_layout_get_hex_cpl (GtkHexLayout *layout)
+{
+ return layout->hex_cpl;
+}
+
/* GtkHexLayoutChild - Public Methods */
void
diff --git a/src/gtkhex-layout-manager.h b/src/gtkhex-layout-manager.h
index 3decd4de..1855a193 100644
--- a/src/gtkhex-layout-manager.h
+++ b/src/gtkhex-layout-manager.h
@@ -29,6 +29,11 @@
G_BEGIN_DECLS
+/* how to group bytes? */
+#define GROUP_BYTE 1
+#define GROUP_WORD 2
+#define GROUP_LONG 4
+
#define GTK_TYPE_HEX_LAYOUT (gtk_hex_layout_get_type ())
G_DECLARE_FINAL_TYPE (GtkHexLayout, gtk_hex_layout, GTK, HEX_LAYOUT,
GtkLayoutManager)
@@ -50,6 +55,10 @@ void gtk_hex_layout_set_char_width (GtkHexLayout *layout,
guint width);
void gtk_hex_layout_child_set_column (GtkHexLayoutChild *child,
GtkHexLayoutColumn column);
+int gtk_hex_layout_get_cpl (GtkHexLayout *layout);
+int gtk_hex_layout_get_hex_cpl (GtkHexLayout *layout);
+void gtk_hex_layout_set_group_type (GtkHexLayout *layout,
+ guint group_type);
G_END_DECLS
diff --git a/src/gtkhex.c b/src/gtkhex.c
index 639f6391..bc0d8eb1 100644
--- a/src/gtkhex.c
+++ b/src/gtkhex.c
@@ -40,7 +40,6 @@
/* Don't move these from the source file as they are not part of the public
* header.
*/
-#include "gtkhex-layout-manager.h"
/* DEFINES */
@@ -51,6 +50,7 @@
#define DEFAULT_CPL 32
#define DEFAULT_LINES 10
#define SCROLL_TIMEOUT 100
+#define STARTING_OFFSET 0
#define is_displayable(c) (((c) >= 0x20) && ((c) < 0x7f))
#define is_copyable(c) (is_displayable(c) || (c) == 0x0a || (c) == 0x0d)
@@ -186,7 +186,6 @@ struct _GtkHex
int scroll_dir;
guint scroll_timeout;
gboolean show_offsets;
- int starting_offset;
gboolean insert;
gboolean selecting;
@@ -199,7 +198,7 @@ struct _GtkHex
int default_lines;
};
-G_DEFINE_TYPE(GtkHex, gtk_hex, GTK_TYPE_WIDGET)
+G_DEFINE_TYPE (GtkHex, gtk_hex, GTK_TYPE_WIDGET)
/* ----- */
@@ -574,7 +573,8 @@ get_char_width (GtkHex *gh)
/* update layout manager */
if (GTK_IS_HEX_LAYOUT(gh->layout_manager)) {
- gtk_hex_layout_set_char_width (gh->layout_manager, width);
+ gtk_hex_layout_set_char_width (GTK_HEX_LAYOUT(gh->layout_manager),
+ width);
}
return width;
}
@@ -602,6 +602,8 @@ format_xblock(GtkHex *gh, gchar *out, guint start, guint end)
int i, j, low, high;
guchar c;
+ g_debug ("%s: GOT GROUP TYPE: %u", __func__, gh->group_type);
+
for(i = start + 1, j = 0; i <= end; i++) {
c = gtk_hex_get_byte(gh, i - 1);
low = c & 0x0F;
@@ -610,7 +612,7 @@ format_xblock(GtkHex *gh, gchar *out, guint start, guint end)
out[j++] = ((high < 10)?(high + '0'):(high - 10 + 'A'));
out[j++] = ((low < 10)?(low + '0'):(low - 10 + 'A'));
- if(i%gh->group_type == 0)
+ if (i % gh->group_type == 0)
out[j++] = ' ';
}
return j;
@@ -881,12 +883,12 @@ render_hex_highlights (GtkHex *gh,
gint cursor_line)
{
GtkHex_Highlight *curHighlight = &gh->selection;
- gint xcpl = gh->cpl*2 + gh->cpl/gh->group_type;
-
GtkHex_AutoHighlight *nextList = gh->auto_highlight;
GtkStateFlags state;
GtkStyleContext *context;
+ int hex_cpl;
+ hex_cpl = gtk_hex_layout_get_hex_cpl (GTK_HEX_LAYOUT(gh->layout_manager));
context = gtk_widget_get_style_context (gh->xdisp);
gtk_style_context_save (context);
@@ -919,7 +921,7 @@ render_hex_highlights (GtkHex *gh,
if (cursor_line == el)
len = 2*(end%gh->cpl + 1) + (end%gh->cpl)/gh->group_type;
else
- len = xcpl;
+ len = hex_cpl;
len = len - cursor_off;
@@ -947,7 +949,7 @@ render_hex_highlights (GtkHex *gh,
gtk_render_background (context, cr,
0,
cursor_line * gh->char_height,
- xcpl * gh->char_width,
+ hex_cpl * gh->char_width,
gh->char_height);
}
}
@@ -1115,12 +1117,16 @@ render_hex_lines (GtkHex *gh,
GtkStateFlags state;
GtkStyleContext *context;
int cursor_line;
- int xcpl = gh->cpl * 2 + gh->cpl / gh->group_type;
int frm_len;
+ int hex_cpl;
g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET(gh)));
g_return_if_fail (gh->cpl > 0);
+ hex_cpl = gtk_hex_layout_get_hex_cpl (GTK_HEX_LAYOUT(gh->layout_manager));
+ g_debug ("%s: GROUP TYPE: %u", __func__, gh->group_type);
+ g_debug ("%s: HEX_CPL: %d", __func__, hex_cpl);
+
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
cursor_line = gh->cursor_pos / gh->cpl - gh->top_line;
@@ -1145,7 +1151,7 @@ render_hex_lines (GtkHex *gh,
for (int i = min_lines; i <= max_lines; i++)
{
- int tmp = frm_len - ((i - min_lines) * xcpl);
+ int tmp = frm_len - ((i - min_lines) * hex_cpl);
if (tmp <= 0)
break;
@@ -1155,8 +1161,8 @@ render_hex_lines (GtkHex *gh,
/* Set pango layout to the line of hex to render. */
pango_layout_set_text (gh->xlayout,
- gh->disp_buffer + (i - min_lines) * xcpl,
- MIN(xcpl, tmp));
+ gh->disp_buffer + (i - min_lines) * hex_cpl,
+ MIN(hex_cpl, tmp));
gtk_render_layout (context, cr,
/* x: */ 0,
@@ -1252,7 +1258,7 @@ render_offsets (GtkHex *gh,
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
- gtk_widget_get_allocation(widget, &allocation);
+ gtk_widget_get_allocation (widget, &allocation);
/* render background. */
gtk_render_background (context, cr,
@@ -1268,7 +1274,7 @@ render_offsets (GtkHex *gh,
for (int i = min_lines; i <= max_lines; i++) {
/* generate offset string and place in temporary buffer */
sprintf(offstr, "%08X",
- (gh->top_line + i) * gh->cpl + gh->starting_offset);
+ (gh->top_line + i) * gh->cpl + STARTING_OFFSET);
/* build pango layout for offset line; draw line with gtk. */
pango_layout_set_text (gh->olayout, offstr, 8);
@@ -1289,51 +1295,13 @@ hex_draw (GtkDrawingArea *drawing_area,
gpointer user_data)
{
GtkHex *gh = GTK_HEX(user_data);
- int xcpl = 0;
g_return_if_fail (GTK_IS_HEX(gh));
- /* Total number of characters that can be displayed per line on the hex
- * widget (xcpl) is the simplest calculation:
- */
- xcpl = width / gh->char_width;
-
- /* FIXME - This doesn't quite jibe with our new layout manager. Our
- * calculations here are fine, but the layout manager has no knowledge
- * of it, so sometimes characters get cut off if using larger group
- * types.
- */
- /* Next, extrapolate the number of ASCII characters per line; this is
- * dependent upon the 'grouping' (ie, hex: 2 characters followed by a
- * space, a 'word' (2 hex characters together followed by a space, ie,
- * 4 + space... this is best illustrated with an example.
- *
- * given 16 xcpl, 'word' grouping:
- *
- * 16 [xcpl] / (2 [fixed value; # characters in a hex pair] * 4
- * [gh->group_type] + 1 [space]) == 1
- *
- * Meaning: 1 full word only can fit on a hex line, in this hypothetical,
- * then multiply the result by the group type again to get the number of
- * _characters_ (ascii) that this represents. (4 * 1 = 4 in this case)
- * Whew!
- */
- gh->cpl = xcpl / (2 * gh->group_type + 1);
- gh->cpl *= gh->group_type;
-
- /* pixel width of hex drawing area */
- gh->xdisp_width = xcpl * gh->char_width;
-
- /* pixel width of ascii drawing area */
- gh->adisp_width = gh->cpl * gh->char_width;
-
- /* If gh->cpl is not greater than 0, something has gone wrong. */
- g_return_if_fail (gh->cpl > 0);
-
/* Now that we have gh->cpl defined, run this function to bump all
* required values:
*/
- recalc_displays(gh);
+ recalc_displays (gh);
/* Finally, we can do what we wanted to do to begin with: draw our hex
* lines!
@@ -1372,10 +1340,12 @@ offsets_draw (GtkDrawingArea *drawing_area,
* lines we can display according to the current size of the widget
*/
static void
-recalc_displays(GtkHex *gh)
+recalc_displays (GtkHex *gh)
{
GtkWidget *widget = GTK_WIDGET (gh);
- int xcpl;
+ int hex_cpl;
+
+ hex_cpl = gtk_hex_layout_get_hex_cpl (GTK_HEX_LAYOUT(gh->layout_manager));
/*
* Only change the value of the adjustment to put the cursor on screen
@@ -1389,15 +1359,10 @@ recalc_displays(GtkHex *gh)
gh->lines++;
}
- /* FIXME - different than 'xcpl' in hex_draw. confusing.
- */
- /* set number of hex characters per line */
- xcpl = gh->cpl * 2 + (gh->cpl - 1) / gh->group_type;
-
if (gh->disp_buffer)
g_free (gh->disp_buffer);
- gh->disp_buffer = g_malloc ((xcpl + 1) * (gh->vis_lines + 1));
+ gh->disp_buffer = g_malloc ((hex_cpl + 1) * (gh->vis_lines + 1));
}
static void
@@ -2466,6 +2431,9 @@ gtk_hex_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
gh->char_width = get_char_width(gh);
gh->char_height = get_char_height(gh);
+ /* Get cpl from layout manager */
+ gh->cpl = gtk_hex_layout_get_cpl (GTK_HEX_LAYOUT(gh->layout_manager));
+
/* get width and height, implicitly converted to floats so we can pass
* to graphene_rect_init below. */
width = gtk_widget_get_allocated_width (widget);
@@ -2725,9 +2693,7 @@ gtk_hex_init(GtkHex *gh)
gh->scroll_timeout = -1;
gh->document = NULL;
- gh->starting_offset = 0;
- gh->xdisp_width = gh->adisp_width = DEFAULT_DA_SIZE;
gh->extra_width = 0;
gh->active_view = VIEW_HEX;
gh->group_type = GROUP_BYTE;
@@ -3284,6 +3250,9 @@ gtk_hex_set_group_type (GtkHex *gh, guint gt)
hide_cursor(gh);
gh->group_type = gt;
+
+ gtk_hex_layout_set_group_type (GTK_HEX_LAYOUT(gh->layout_manager), gt);
+
#if 0
gtk_widget_get_allocation(GTK_WIDGET(gh), &allocation);
recalc_displays(gh, allocation.width, allocation.height);
@@ -3312,14 +3281,6 @@ gtk_hex_show_offsets(GtkHex *gh, gboolean show)
hide_offsets_widget(gh);
}
-void
-gtk_hex_set_starting_offset (GtkHex *gh, gint starting_offset)
-{
- g_return_if_fail (gh != NULL);
- g_return_if_fail(GTK_IS_HEX(gh));
- gh->starting_offset = starting_offset;
-}
-
void
gtk_hex_set_insert_mode (GtkHex *gh, gboolean insert)
{
diff --git a/src/gtkhex.h b/src/gtkhex.h
index 124bbd6d..6194c457 100644
--- a/src/gtkhex.h
+++ b/src/gtkhex.h
@@ -36,19 +36,13 @@
#include <gdk/gdk.h>
#include <hex-document.h>
+#include <gtkhex-layout-manager.h>
G_BEGIN_DECLS
#define GTK_TYPE_HEX (gtk_hex_get_type ())
G_DECLARE_FINAL_TYPE(GtkHex, gtk_hex, GTK, HEX, GtkWidget)
-/* DEFINES */
-
-/* how to group bytes? */
-#define GROUP_BYTE 1
-#define GROUP_WORD 2
-#define GROUP_LONG 4
-
/* OPAQUE DATATYPES */
typedef struct _GtkHex_AutoHighlight GtkHex_AutoHighlight;
@@ -67,7 +61,6 @@ guchar gtk_hex_get_byte(GtkHex *, guint);
void gtk_hex_set_group_type(GtkHex *, guint);
guint gtk_hex_get_group_type (GtkHex *gh);
-void gtk_hex_set_starting_offset(GtkHex *, gint);
void gtk_hex_show_offsets(GtkHex *, gboolean);
void gtk_hex_set_font(GtkHex *, PangoFontMetrics *,
const PangoFontDescription *);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]