static int best_direction(const Point* grid_point, const Rect* client_rects, int n_client_rects, const Rect* monitor, const Size* req_size, Point* best_top_left) { static const Size directions[NUM_DIRECTIONS] = { {0, 0}, {0, -1}, {-1, 0}, {-1, -1} }; int overlap = G_MAXINT; int i; for (i = 0; i < NUM_DIRECTIONS; ++i) { Point pt = { .x = grid_point->x + (req_size->width * directions[i].width), .y = grid_point->y + (req_size->height * directions[i].height) }; Rect r; RECT_SET(r, pt.x, pt.y, req_size->width, req_size->height); if (!RECT_CONTAINS_RECT(*monitor, r)) continue; int this_overlap = total_overlap(client_rects, n_client_rects, &r); if (this_overlap < overlap) { overlap = this_overlap; *best_top_left = pt; } if (overlap == 0) break; } return overlap; }
int BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out) { RECT_T *pPrevLine = NULL, *pFirst = out, *pThis = pFirst; int i, j, i0; int length; for (j = 0; j < pSrcRect->numLines; j++) { /* generate data for a scanline */ byte_t *pSrc = (byte_t *) pSrcRect->pBits + j * pSrcRect->stride; RECT_T *pLine = pThis; i = 0; do { while (i < pSrcRect->numSamples && getRGBA(pSrc, pSrcRect->format) < ALPHA_THRESHOLD) { pSrc += pSrcRect->depthBytes; ++i; } if (i >= pSrcRect->numSamples) { break; } i0 = i; while (i < pSrcRect->numSamples && getRGBA(pSrc, pSrcRect->format) >= ALPHA_THRESHOLD) { pSrc += pSrcRect->depthBytes; ++i; } RECT_SET(*pThis, i0, j, i - i0, 1); ++pThis; } while (i < pSrcRect->numSamples); /* check if the previous scanline is exactly the same, merge if so (this is the only optimization we can use for YXBanded rectangles, and win32 supports YXBanded only */ length = pThis - pLine; if (pPrevLine && pLine - pPrevLine == length) { for (i = 0; i < length && RECT_EQ_X(pPrevLine[i], pLine[i]); ++i) { } if (i == pLine - pPrevLine) { // do merge for (i = 0; i < length; i++) { RECT_INC_HEIGHT(pPrevLine[i]); } pThis = pLine; continue; } } /* or else use the generated scanline */ pPrevLine = pLine; } return pThis - pFirst; }
void popup_delay_show(ObPopup *self, gulong msec, gchar *text) { gint l, t, r, b; gint x, y, w, h; guint m; gint emptyx, emptyy; /* empty space between elements */ gint textx, texty, textw, texth; gint iconx, icony, iconw, iconh; const Rect *area; Rect mon; gboolean hasicon = self->hasicon; /* when there is no icon and the text is not parent relative, then fill the whole dialog with the text appearance, don't use the bg at all */ if (hasicon || self->a_text->surface.grad == RR_SURFACE_PARENTREL) RrMargins(self->a_bg, &l, &t, &r, &b); else l = t = r = b = 0; /* set up the textures */ self->a_text->texture[0].data.text.string = text; /* measure the text out */ if (text[0] != '\0') { RrMinSize(self->a_text, &textw, &texth); } else { textw = 0; texth = RrMinHeight(self->a_text); } /* get the height, which is also used for the icon width */ emptyy = t + b + ob_rr_theme->paddingy * 2; if (self->h) texth = self->h - emptyy; h = texth * self->iconhm + emptyy; if (self->textw) textw = self->textw; iconx = textx = l + ob_rr_theme->paddingx; emptyx = l + r + ob_rr_theme->paddingx * 2; if (hasicon) { iconw = texth * self->iconwm; iconh = texth * self->iconhm; textx += iconw + ob_rr_theme->paddingx; if (textw) emptyx += ob_rr_theme->paddingx; /* between the icon and text */ icony = (h - iconh - emptyy) / 2 + t + ob_rr_theme->paddingy; } else iconw = 0; texty = (h - texth - emptyy) / 2 + t + ob_rr_theme->paddingy; /* when there is no icon, then fill the whole dialog with the text appearance */ if (!hasicon) { textx = texty = 0; texth += emptyy; textw += emptyx; emptyx = emptyy = 0; } w = textw + emptyx + iconw; /* cap it at maxw/minw */ if (self->maxw) w = MIN(w, self->maxw); if (self->minw) w = MAX(w, self->minw); textw = w - emptyx - iconw; /* sanity checks to avoid crashes! */ if (w < 1) w = 1; if (h < 1) h = 1; if (texth < 1) texth = 1; /* set up the x coord */ x = self->x; switch (self->gravity) { case NorthGravity: case CenterGravity: case SouthGravity: x -= w / 2; break; case NorthEastGravity: case EastGravity: case SouthEastGravity: x -= w; break; } /* set up the y coord */ y = self->y; switch (self->gravity) { case WestGravity: case CenterGravity: case EastGravity: y -= h / 2; break; case SouthWestGravity: case SouthGravity: case SouthEastGravity: y -= h; break; } /* Find the monitor which contains the biggest part of the popup. * If the popup is completely off screen, limit it to the intersection * of all monitors and then try again. If it's still off screen, put it * on monitor 0. */ RECT_SET(mon, x, y, w, h); m = screen_find_monitor(&mon); area = screen_physical_area_monitor(m); x=MAX(MIN(x, area->x+area->width-w),area->x); y=MAX(MIN(y, area->y+area->height-h),area->y); if (m == screen_num_monitors) { RECT_SET(mon, x, y, w, h); m = screen_find_monitor(&mon); if (m == screen_num_monitors) m = 0; area = screen_physical_area_monitor(m); x=MAX(MIN(x, area->x+area->width-w),area->x); y=MAX(MIN(y, area->y+area->height-h),area->y); } /* set the windows/appearances up */ XMoveResizeWindow(obt_display, self->bg, x, y, w, h); /* when there is no icon and the text is not parent relative, then fill the whole dialog with the text appearance, don't use the bg at all */ if (hasicon || self->a_text->surface.grad == RR_SURFACE_PARENTREL) RrPaint(self->a_bg, self->bg, w, h); if (textw) { self->a_text->surface.parent = self->a_bg; self->a_text->surface.parentx = textx; self->a_text->surface.parenty = texty; XMoveResizeWindow(obt_display, self->text, textx, texty, textw, texth); RrPaint(self->a_text, self->text, textw, texth); } if (hasicon) self->draw_icon(iconx, icony, iconw, iconh, self->draw_icon_data); /* do the actual showing */ if (!self->mapped) { if (msec) { /* don't kill previous show timers */ if (!self->delay_mapped) { self->delay_timer = g_timeout_add(msec, popup_show_timeout, self); self->delay_mapped = TRUE; } } else { popup_show_timeout(self); } } }