From b2ed4a6920410af4cb9ce0150d32d4888d5b35e1 Mon Sep 17 00:00:00 2001 From: rds <rds> Date: Mon, 6 Nov 2006 09:32:04 +0000 Subject: [PATCH] filter locus names so only one instance with same name is drawn. correct initialisation and sizing of the locator. better method for calculating x dimensions. --- src/zmapWindow/zmapWindowNavigator.c | 508 +++++++++++++++++++-------- 1 file changed, 368 insertions(+), 140 deletions(-) diff --git a/src/zmapWindow/zmapWindowNavigator.c b/src/zmapWindow/zmapWindowNavigator.c index bb916bdf1..2a5b59bfa 100755 --- a/src/zmapWindow/zmapWindowNavigator.c +++ b/src/zmapWindow/zmapWindowNavigator.c @@ -27,9 +27,9 @@ * * Exported functions: See XXXXXXXXXXXXX.h * HISTORY: - * Last edited: Oct 24 14:57 2006 (rds) + * Last edited: Nov 3 17:41 2006 (rds) * Created: Wed Sep 6 11:22:24 2006 (rds) - * CVS info: $Id: zmapWindowNavigator.c,v 1.3 2006-10-24 13:59:08 rds Exp $ + * CVS info: $Id: zmapWindowNavigator.c,v 1.4 2006-11-06 09:32:04 rds Exp $ *------------------------------------------------------------------- */ @@ -41,6 +41,9 @@ #include <ZMap/zmapNavigatorStippleG.xbm> /* bitmap... */ +/* Return the widget! */ +#define NAVIGATOR_WIDGET(navigate) GTK_WIDGET(fetchCanvas(navigate)) + typedef struct { gpointer user_data; @@ -81,6 +84,13 @@ typedef struct double offset ; } PositionColumnStruct, *PositionColumn ; +typedef struct +{ + double start, end; + ZMapStrand strand; + ZMapFeature feature; +} LocusEntryStruct, *LocusEntry; + /* We need this because the locator is drawn as a foo_canvas_rect with * a transparent background, that will not receive events! Therefore as * a work around we set up a handler on the root background and test @@ -97,12 +107,7 @@ static ZMapFeatureContextExecuteStatus drawContext(GQuark key, gpointer data, gpointer user_data, char **err_out); -static ZMapFeatureContextExecuteStatus positionColumns(GQuark key, - gpointer data, - gpointer user_data, - char **err_out); static void createColumnCB(gpointer data, gpointer user_data); -static void positionColumnCB(gpointer data, gpointer user_data); static void clampCoords(ZMapWindowNavigator navigate, double pre_scale, double post_scale, @@ -115,6 +120,7 @@ static void setupLocatorGroup(ZMapWindowNavigator navigate); static void updateLocatorDragger(ZMapWindowNavigator navigate, double button_y, double size); static gboolean rootBGEventCB(FooCanvasItem *item, GdkEvent *event, gpointer data); static gboolean columnBackgroundEventCB(FooCanvasItem *item, GdkEvent *event, gpointer data); +static void positioningCB(FooCanvasGroup *container, FooCanvasPoints *points, gpointer user_data); static FooCanvas *fetchCanvas(ZMapWindowNavigator navigate); @@ -142,6 +148,13 @@ static gboolean factoryFeatureSizeReq(ZMapFeature feature, /* ------------------- */ +static GQuark locus_id_G = 0; + +static void destroyLocusEntry(gpointer data) +{ + return ; +} + /* create */ ZMapWindowNavigator zMapWindowNavigatorCreate(GtkWidget *canvas_widget) { @@ -149,6 +162,8 @@ ZMapWindowNavigator zMapWindowNavigatorCreate(GtkWidget *canvas_widget) zMapAssert(FOO_IS_CANVAS(canvas_widget)); + locus_id_G = g_quark_from_string("locus"); + if((navigate = g_new0(ZMapWindowNavigatorStruct, 1))) { FooCanvas *canvas = NULL; @@ -157,6 +172,8 @@ ZMapWindowNavigator zMapWindowNavigatorCreate(GtkWidget *canvas_widget) navigate->ftoi_hash = zmapWindowFToICreate(); + navigate->locus_display_hash = g_hash_table_new_full(NULL, NULL, NULL, destroyLocusEntry); + if(USE_BACKGROUNDS) { gdk_color_parse(ROOT_BACKGROUND, &(navigate->root_background)); @@ -260,8 +277,10 @@ void zMapWindowNavigatorDrawFeatures(ZMapWindowNavigator navigate, draw_data.navigate = navigate; draw_data.context = full_context; - navigate->span.x1 = full_context->sequence_to_parent.c1; - navigate->span.x2 = full_context->sequence_to_parent.c2; + navigate->full_span.x1 = full_context->sequence_to_parent.c1; + navigate->full_span.x2 = full_context->sequence_to_parent.c2; + + navigate->scaling_factor = NAVIGATOR_SIZE / (navigate->full_span.x2 - navigate->full_span.x1 + 1.0); canvas = fetchCanvas(navigate); @@ -275,7 +294,7 @@ void zMapWindowNavigatorDrawFeatures(ZMapWindowNavigator navigate, } else { - navigateDrawFunc(&draw_data, GTK_WIDGET(fetchCanvas(navigate))); + navigateDrawFunc(&draw_data, GTK_WIDGET(canvas)); } return ; @@ -294,6 +313,9 @@ void zMapWindowNavigatorDrawLocator(ZMapWindowNavigator navigate, rx1 = navigate->locator_x1; rx2 = navigate->locator_x2; + navigate->locator_span.x1 = raw_top; + navigate->locator_span.x2 = raw_bot; + if(raw_top == 0.0 && raw_top == raw_bot) { foo_canvas_item_get_bounds(FOO_CANVAS_ITEM(navigate->locator_drag), @@ -338,7 +360,7 @@ void zmapWindowNavigatorPositioning(ZMapWindowNavigator navigate) * this call to container execute. */ zmapWindowContainerExecuteFull(navigate->container_align, ZMAPCONTAINER_LEVEL_FEATURESET, - NULL, NULL, NULL, NULL, TRUE); + NULL, NULL, positioningCB, navigate, TRUE); /* ***************************** i.e. here ^^^^, ^^^^ */ return ; @@ -357,6 +379,63 @@ void zMapWindowNavigatorDestroy(ZMapWindowNavigator navigate) /* INTERNAL */ +static void positioningCB(FooCanvasGroup *container, FooCanvasPoints *points, gpointer user_data) +{ + ZMapWindowNavigator navigate = (ZMapWindowNavigator)user_data; + FooCanvasGroup *align = NULL; + double init_y1, init_y2, init_size; + double rx1, rx2, width_x; + ZMapContainerLevelType level ; + + level = zmapWindowContainerGetLevel(container) ; + + switch(level) + { + case ZMAPCONTAINER_LEVEL_ALIGN: + { + GtkWidget *widget = NULL; + + if(navigate->locator_span.x1 == navigate->locator_span.x2) + { + init_y1 = (double)(navigate->full_span.x1); + init_y2 = (double)(navigate->full_span.x2); + } + else + { + init_y1 = (double)(navigate->locator_span.x1); + init_y2 = (double)(navigate->locator_span.x2); + } + + init_size = init_y2 - init_y1; + + align = zmapWindowContainerGetFeatures(navigate->container_align); + width_x = (double)(navigate->locator_width) + 1.0; + + foo_canvas_item_get_bounds(FOO_CANVAS_ITEM(align), + &rx1, NULL, + &rx2, NULL); + + navigate->locator_x1 = rx1 + width_x; + navigate->locator_x2 = rx2 + width_x; + + zMapWindowNavigatorDrawLocator(navigate, init_y1, init_y2); + + widget = NAVIGATOR_WIDGET(navigate); + + zmapWindowNavigatorSizeRequest(widget, rx2 - rx1 + 1.0, init_size); + } + break; + case ZMAPCONTAINER_LEVEL_ROOT: + case ZMAPCONTAINER_LEVEL_BLOCK: + case ZMAPCONTAINER_LEVEL_FEATURESET: + case ZMAPCONTAINER_LEVEL_STRAND: + default: + break; + } + + return ; +} + static FooCanvas *fetchCanvas(ZMapWindowNavigator navigate) { FooCanvas *canvas = NULL; @@ -371,73 +450,215 @@ static FooCanvas *fetchCanvas(ZMapWindowNavigator navigate) return canvas; } -#ifdef RDS_NO_INITIAL_BUMPING_ -static ZMapFeatureContextExecuteStatus positionColumns(GQuark key_id, - gpointer data, - gpointer user_data, - char **error_out) +static gboolean navExposeHandlerCB(GtkWidget *widget, GdkEventExpose *expose, gpointer user_data) { - ZMapFeatureAny feature_any = (ZMapFeatureAny)data; - ZMapFeatureContext feature_block = NULL; - ZMapFeatureStructType feature_type = ZMAPFEATURE_STRUCT_INVALID; - ZMapFeatureContextExecuteStatus status = ZMAP_CONTEXT_EXEC_STATUS_OK; + NavigateDraw draw_data = (NavigateDraw)user_data; + + g_signal_handler_disconnect(G_OBJECT(widget), draw_data->expose_handler_id); + + navigateDrawFunc(draw_data, widget); + + g_free(draw_data); + + return FALSE; /* lets others run. */ +} + +typedef struct +{ + GList *list_start; + GList *list_end; + ZMapWindowNavigator navigate; + FooCanvasItem *item; + double wheight; + double last_movement; +}UnOverlapTextDataStruct, *UnOverlapTextData; + +typedef struct +{ + FooCanvasItem *item; + gboolean overlapped; + gboolean start_overlap, end_overlap; + double overlap_at_start, overlap_at_end, cummulative; + double wy1, wy2; + double iy1, iy2; + int cy1, cy2; +}TextualDataStruct, *TextualData; + +static void locus_gh_func(gpointer hash_key, gpointer hash_value, gpointer user_data) +{ + UnOverlapTextData data = (UnOverlapTextData)user_data; + ZMapFeature feature = NULL; + LocusEntry locus_data = (LocusEntry)hash_value; + TextualData text_data = NULL; + double text_height, start, end, mid, draw_here, dummy_x = 0.0, i2w_dy; + int cx = 0; + + if((text_data = g_new0(TextualDataStruct, 1))) + { + feature = locus_data->feature; + start = locus_data->start; + end = locus_data->end; + + if((text_data->item = zmapWindowFToIFindFeatureItem(data->navigate->ftoi_hash, + locus_data->strand, ZMAPFRAME_NONE, + feature))) + { + double x1, x2, y1, y2; + text_height = data->wheight; + mid = start + ((end - start + 1.0) / 2.0); + draw_here = mid - (text_height / 2.0); + + text_data->iy1 = text_data->wy1 = start; + text_data->iy2 = text_data->wy2 = start + text_height; + + foo_canvas_item_get_bounds(text_data->item, &x1, &y1, &x2, &y2); + + /* move to the start of the locus... */ + foo_canvas_item_move(text_data->item, 0.0, start - y1); + + foo_canvas_item_get_bounds(text_data->item, &x1, &(text_data->iy1), &x2, &(text_data->iy2)); + + text_data->wy1 = text_data->iy1; + text_data->wy2 = text_data->iy2; + + foo_canvas_item_i2w(text_data->item, &dummy_x, &(text_data->wy1)); + foo_canvas_item_i2w(text_data->item, &dummy_x, &(text_data->wy2)); + + foo_canvas_w2c(text_data->item->canvas, dummy_x, text_data->wy1, &cx, &(text_data->cy1)); + foo_canvas_w2c(text_data->item->canvas, dummy_x, text_data->wy2, &cx, &(text_data->cy2)); + + text_data->overlap_at_start = + text_data->overlap_at_end = + text_data->cummulative = 0.0; + + if(data->list_end) + { + data->list_end = g_list_append(data->list_end, text_data); + data->list_end = data->list_end->next; + } + else + data->list_start = + data->list_end = g_list_append(data->list_start, text_data); + } + else + zMapAssertNotReached(); + } - feature_type = feature_any->struct_type; + return ; +} +static void do_unoverlap(gpointer list_data, gpointer user_data) +{ - switch(feature_type) + return ; +} + +static gint sort_text_position(gconstpointer member_a, gconstpointer member_b) +{ + TextualData text_a = (TextualData)member_a, + text_b = (TextualData)member_b; + gint position = 0; /* negative value if a < b; zero if a = b; positive value if a > b. */ + gboolean lt1, lt2, gt1, gt2; + double ay1, ay2, by1, by2; + + lt1 = lt2 = gt1 = gt2 = FALSE; + + if(1) { - case ZMAPFEATURE_STRUCT_BLOCK: - { - NavigateDraw draw_data = (NavigateDraw)user_data; - PositionColumnStruct pcs = { SHIFT_COLUMNS_LEFT }; - FooCanvasGroup *strand_group = NULL; + ay1 = (double)(text_a->cy1); + ay2 = (double)(text_a->cy2); + by1 = (double)(text_b->cy1); + by2 = (double)(text_b->cy2); + } + else + { + ay1 = text_a->wy1; + ay2 = text_a->wy2; + by1 = text_b->wy1; + by2 = text_b->wy2; + } - feature_block = (ZMapFeatureBlock)feature_any; - strand_group = FOO_CANVAS_GROUP(zmapWindowContainerGetFeatures(draw_data->container_strand)); + if( (( lt1 = (ay1 < by1) ) && + ( lt2 = (ay2 > by1) )) + || + (( gt1 = (ay2 > by2) ) && + ( gt2 = (ay1 < by2) )) + ) + { + double tmp = 0.0; + text_a->overlapped = text_b->overlapped = TRUE; + if(gt1) + { + text_a->start_overlap = + text_b->end_overlap = TRUE; + text_a->overlap_at_start = + text_b->overlap_at_end = tmp = by2 - ay1; + } + if(lt1) + { + text_b->start_overlap = + text_a->end_overlap = TRUE; + text_b->overlap_at_start = + text_a->overlap_at_end = tmp = ay2 - by1; + } + text_a->cummulative += tmp; + text_b->cummulative += tmp; + } - g_list_foreach(FOO_CANVAS_GROUP(strand_group)->item_list, positionColumnCB, &pcs); - } - break; - case ZMAPFEATURE_STRUCT_ALIGN: - { - NavigateDraw draw_data = (NavigateDraw)user_data; - zmapWindowContainerMaximiseBackground(draw_data->navigate->container_root); - } - break; - case ZMAPFEATURE_STRUCT_CONTEXT: - case ZMAPFEATURE_STRUCT_FEATURESET: - break; - case ZMAPFEATURE_STRUCT_FEATURE: - case ZMAPFEATURE_STRUCT_INVALID: - default: - status = ZMAP_CONTEXT_EXEC_STATUS_ERROR; - *error_out = g_strdup("Why are we here?"); - break; + + /* can only rely on lt1 and gt1 to have been evaluated... */ + /* i'm relying on the fact that all items are the same + * height here. */ + if(lt1) + { + position = -1; + printf("-"); } + else if(gt1) + { + position = 1; + printf("+"); + } + else + printf("."); - return status; + return position; /* negative value if a < b; zero if a = b; positive value if a > b. */ } -#endif /* RDS_NO_INITIAL_BUMPING_ */ -static gboolean navExposeHandlerCB(GtkWidget *widget, GdkEventExpose *expose, gpointer user_data) +static void unOverlapText(ZMapWindowNavigator navigate) { - NavigateDraw draw_data = (NavigateDraw)user_data; + UnOverlapTextDataStruct locus_gh_data = {NULL}; - g_signal_handler_disconnect(G_OBJECT(widget), draw_data->expose_handler_id); + if(navigate->locus_display_hash) + { + FooCanvas *canvas = NULL; - navigateDrawFunc(draw_data, widget); + canvas = fetchCanvas(navigate); - g_free(draw_data); + locus_gh_data.navigate = navigate; - return FALSE; /* lets others run. */ + zmapWindowNavigatorTextSize(GTK_WIDGET(canvas), + NULL, &(locus_gh_data.wheight)); + locus_gh_data.wheight -= (3.0 / canvas->pixels_per_unit_y); + + g_hash_table_foreach(navigate->locus_display_hash, + locus_gh_func, + &locus_gh_data); +#ifdef RDS_DONT_INCLUDE + printf("\nunOverlapText: sorting first ...\n"); + locus_gh_data.list_start = g_list_sort(locus_gh_data.list_start, sort_text_position); + locus_gh_data.list_end = g_list_last(locus_gh_data.list_start); + printf("\nunOverlapText: doing unoverlap ...\n"); + g_list_foreach(locus_gh_data.list_start, do_unoverlap, &locus_gh_data); + printf("\nunOverlapText: finished\n"); +#endif + } + + return ; } static void navigateDrawFunc(NavigateDraw nav_draw, GtkWidget *widget) { ZMapWindowNavigator navigate = nav_draw->navigate; - FooCanvasGroup *align = NULL; - double init_y1, init_y2, init_size; - double rx1, rx2, width_x; /* Everything to get a context drawn, raised to top and visible. */ zMapFeatureContextExecuteComplete((ZMapFeatureAny)(nav_draw->context), @@ -446,27 +667,13 @@ static void navigateDrawFunc(NavigateDraw nav_draw, GtkWidget *widget) NULL, nav_draw); zmapWindowNavigatorPositioning(navigate); + + unOverlapText(navigate); + + /* DO THIS ON FRIDAY! */ /* port below into positioning! */ foo_canvas_item_raise_to_top(FOO_CANVAS_ITEM(navigate->container_root)); - init_y1 = (double)(navigate->span.x1); - init_y2 = (double)(navigate->span.x2); - init_size = init_y2 - init_y1; - - align = zmapWindowContainerGetFeatures(navigate->container_align); - width_x = (double)(navigate->locator_width) + 1.0; - - foo_canvas_item_get_bounds(FOO_CANVAS_ITEM(align), - &rx1, NULL, - &rx2, NULL); - - navigate->locator_x1 = rx1 + width_x; - navigate->locator_x2 = rx2 + width_x; - - zMapWindowNavigatorDrawLocator(navigate, init_y1, init_size); - - zmapWindowNavigatorSizeRequest(widget, rx2 - rx1 + 1.0, init_size); - zmapWindowNavigatorFillWidget(widget); return ; @@ -521,7 +728,7 @@ static ZMapFeatureContextExecuteStatus drawContext(GQuark key_id, block_start = feature_block->block_to_sequence.q1; block_end = feature_block->block_to_sequence.q2; - draw_data->navigate->scaling_factor = NAVIGATOR_SIZE / (block_end - block_start + 1.0); + //draw_data->navigate->scaling_factor = NAVIGATOR_SIZE / (block_end - block_start + 1.0); /* create the block and add the item to the hash */ features = zmapWindowContainerGetFeatures(draw_data->navigate->container_align); @@ -679,45 +886,6 @@ static void createColumnCB(gpointer data, gpointer user_data) return ; } -#ifdef RDS_NO_INITIAL_BUMPING_ -/* Note how we must look at the items drawn, _not_ whether there are any features in the feature - * set because the features may not be drawn (e.g. because they are on the opposite strand. */ -static void positionColumnCB(gpointer data, gpointer user_data) -{ - FooCanvasGroup *container = (FooCanvasGroup *)data ; - FooCanvasGroup *parent ; - PositionColumn pos_data = (PositionColumn)user_data ; - double x1, y1, x2, y2 ; - ZMapFeatureTypeStyle style ; - double spacing ; - - parent = zmapWindowContainerGetSuperGroup(container) ; - - spacing = zmapWindowContainerGetSpacing(parent) ; - - style = zmapWindowContainerGetStyle(container) ; - zMapAssert(style) ; - -#ifdef RDS_BUMP_BROKEN - /* Bump columns that need to be bumped. */ - if (style->overlap_mode != ZMAPOVERLAP_COMPLETE) - zmapWindowColumnBump(FOO_CANVAS_ITEM(container), style->overlap_mode) ; -#endif - - /* Set its x position. */ - my_foo_canvas_item_goto(FOO_CANVAS_ITEM(container), &(pos_data->offset), NULL) ; - - zmapWindowContainerMaximiseBackground(container); - - /* Calculate the offset of the next column from this ones width. */ - foo_canvas_item_get_bounds(FOO_CANVAS_ITEM(container), &x1, &y1, &x2, &y2) ; - - pos_data->offset = pos_data->offset + zmapWindowExt(x1, x2) + spacing ; - - return ; -} -#endif /* RDS_NO_INITIAL_BUMPING_ */ - static void setupLocatorGroup(ZMapWindowNavigator navigate) { FooCanvasGroup *locator_grp = NULL; @@ -805,8 +973,8 @@ static void clampCoords(ZMapWindowNavigator navigate, double top, bot; double min, max; - min = (double)(navigate->span.x1) * pre_scale; - max = (double)(navigate->span.x2) * pre_scale; + min = (double)(navigate->full_span.x1) * pre_scale; + max = (double)(navigate->full_span.x2) * pre_scale; top = *c1_inout; bot = *c2_inout; @@ -940,7 +1108,7 @@ static gboolean rootBGEventCB(FooCanvasItem *item, GdkEvent *event, gpointer dat zMapWindowNavigatorDrawLocator(navigate, locator_y1, locator_y2); if(locator_y1 != origin_y1 && locator_y2 != origin_y2) - zmapWindowNavigatorValueChanged(GTK_WIDGET(fetchCanvas(navigate)), locator_y1, locator_y2); + zmapWindowNavigatorValueChanged(NAVIGATOR_WIDGET(navigate), locator_y1, locator_y2); transp_data->locator_click = FALSE; @@ -993,7 +1161,8 @@ static void makeMenuFromCanvasItem(GdkEventButton *button, FooCanvasItem *item, ZMapFeatureAny feature_any = NULL; GList *menu_sets = NULL; char *menu_title = NULL; - gboolean bumping_works = FALSE; + gboolean bumping_works = TRUE; + ZMapFeatureTypeStyle style = NULL; feature_any = g_object_get_data(G_OBJECT(item), ITEM_FEATURE_DATA); @@ -1001,13 +1170,27 @@ static void makeMenuFromCanvasItem(GdkEventButton *button, FooCanvasItem *item, if((menu_data = g_new0(NavigateMenuCBDataStruct, 1))) { - menu_data->item_cb = (feature_any->struct_type == ZMAPFEATURE_STRUCT_FEATURE ? TRUE : FALSE); menu_data->item = item; menu_data->navigate = (ZMapWindowNavigator)data; + if(feature_any->struct_type == ZMAPFEATURE_STRUCT_FEATURE) + { + style = zmapWindowItemGetStyle(item) ; + menu_data->item_cb = TRUE; + } + else + { + /* get set_data->style */ + ZMapWindowItemFeatureSetData set_data ; + set_data = g_object_get_data(G_OBJECT(item), ITEM_FEATURE_SET_DATA) ; + zMapAssert(set_data) ; + style = set_data->style ; + menu_data->item_cb = FALSE; + } + if(bumping_works) { - menu_sets = g_list_append(menu_sets, zmapWindowNavigatorMakeMenuBump(NULL, NULL, menu_data, 0)); + menu_sets = g_list_append(menu_sets, zmapWindowNavigatorMakeMenuBump(NULL, NULL, menu_data, zMapStyleGetOverlapMode(style))); menu_sets = g_list_append(menu_sets, separator); } @@ -1141,30 +1324,75 @@ static gboolean factoryFeatureSizeReq(ZMapFeature feature, double *x2_inout = &(points_array_inout[3]); int start_end_crossing = 0; double block_start, block_end; + LocusEntry hash_entry = NULL; scale_factor = navigate->scaling_factor; - block_start = limits_array[1] * scale_factor; - block_end = limits_array[3] * scale_factor; - - *x1_inout = *x1_inout * scale_factor; - *x2_inout = *x2_inout * scale_factor; + if(locus_id_G == feature->parent->unique_id) + { + points_array_inout[0] += 20; + points_array_inout[2] += 20; + if((hash_entry = g_hash_table_lookup(navigate->locus_display_hash, + GUINT_TO_POINTER(feature->original_id)))) + { + /* we only ever draw the first one of these. */ + outside = TRUE; + } + else if((hash_entry = g_new0(LocusEntryStruct, 1))) + { + hash_entry->start = *x1_inout * scale_factor; + hash_entry->end = *x2_inout * scale_factor; + hash_entry->strand = feature->strand; + hash_entry->feature = feature; /* So we can find the item */ + g_hash_table_insert(navigate->locus_display_hash, + GUINT_TO_POINTER(feature->original_id), + (gpointer)hash_entry); + outside = FALSE; + } + else + { + zMapAssertNotReached(); + } + } +#ifdef RDS_DONT_INCLUDE + if(!outside) + { +#endif + + block_start = limits_array[1] * scale_factor; + block_end = limits_array[3] * scale_factor; + + *x1_inout = *x1_inout * scale_factor; + *x2_inout = *x2_inout * scale_factor; + + /* shift according to how we cross, like this for ease of debugging, not speed */ + start_end_crossing |= ((*x1_inout < block_start) << 1); + start_end_crossing |= ((*x2_inout > block_end) << 2); + start_end_crossing |= ((*x1_inout > block_end) << 3); + start_end_crossing |= ((*x2_inout < block_start) << 4); + + /* Now check whether we cross! */ + if(start_end_crossing & 8 || + start_end_crossing & 16) /* everything is out of range don't display! */ + outside = TRUE; - /* shift according to how we cross, like this for ease of debugging, not speed */ - start_end_crossing |= ((*x1_inout < block_start) << 1); - start_end_crossing |= ((*x2_inout > block_end) << 2); - start_end_crossing |= ((*x1_inout > block_end) << 3); - start_end_crossing |= ((*x2_inout < block_start) << 4); + if(start_end_crossing & 2) + *x1_inout = block_start; + if(start_end_crossing & 4) + *x2_inout = block_end; - /* Now check whether we cross! */ - if(start_end_crossing & 8 || - start_end_crossing & 16) /* everything is out of range don't display! */ - outside = TRUE; + if(hash_entry) + { + /* extend the values in the hash list */ + if(hash_entry->start > *x1_inout) + hash_entry->start = *x1_inout; + if(hash_entry->end < *x2_inout) + hash_entry->end = *x2_inout; + } - if(start_end_crossing & 2) - *x1_inout = block_start; - if(start_end_crossing & 4) - *x2_inout = block_end; +#ifdef RDS_DONT_INCLUDE + } +#endif return outside; } -- GitLab