Exemple #1
0
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;
}
Exemple #3
0
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);
        }
    }
}