예제 #1
0
파일: t-gob.c 프로젝트: xqlab/r3
*/	static void Detach_Gob(REBGOB *gob)
/*
**		Remove a gob value from its parent.
**		Done normally in advance of inserting gobs into new parent.
**
***********************************************************************/
{
    REBGOB *par;
    REBINT i;

    par = GOB_PARENT(gob);
    if (par && GOB_PANE(par) && (i = Find_Gob(par, gob)) != NOT_FOUND) {
        Remove_Series(GOB_PANE(par), i, 1);
    }
    GOB_PARENT(gob) = 0;
}
예제 #2
0
파일: t-gob.c 프로젝트: xqlab/r3
*/	static void Remove_Gobs(REBGOB *gob, REBCNT index, REBCNT len)
/*
**		Remove one or more gobs from a pane at the given index.
**
***********************************************************************/
{
    REBGOB **ptr;
    REBCNT n;

    ptr = GOB_SKIP(gob, index);
    for (n = 0; n < len; n++, ptr++) {
        GOB_PARENT(*ptr) = 0;
    }

    Remove_Series(GOB_PANE(gob), index, len);
}
예제 #3
0
파일: t-gob.c 프로젝트: xqlab/r3
*/	static REBFLG Get_GOB_Var(REBGOB *gob, REBVAL *word, REBVAL *val)
/*
***********************************************************************/
{
    switch (VAL_WORD_CANON(word)) {

    case SYM_OFFSET:
        SET_PAIR(val, GOB_X(gob), GOB_Y(gob));
        break;

    case SYM_SIZE:
        SET_PAIR(val, GOB_W(gob), GOB_H(gob));
        break;

    case SYM_IMAGE:
        if (GOB_TYPE(gob) == GOBT_IMAGE) {
            // image
        }
        else goto is_none;
        break;

    case SYM_DRAW:
        if (GOB_TYPE(gob) == GOBT_DRAW) {
            Set_Block(val, GOB_CONTENT(gob)); // Note: compiler optimizes SET_BLOCKs below
        }
        else goto is_none;
        break;

    case SYM_TEXT:
        if (GOB_TYPE(gob) == GOBT_TEXT) {
            Set_Block(val, GOB_CONTENT(gob));
        }
        else if (GOB_TYPE(gob) == GOBT_STRING) {
            Set_String(val, GOB_CONTENT(gob));
        }
        else goto is_none;
        break;

    case SYM_EFFECT:
        if (GOB_TYPE(gob) == GOBT_EFFECT) {
            Set_Block(val, GOB_CONTENT(gob));
        }
        else goto is_none;
        break;

    case SYM_COLOR:
        if (GOB_TYPE(gob) == GOBT_COLOR) {
            Set_Tuple_Pixel((REBYTE*)&GOB_CONTENT(gob), val);
        }
        else goto is_none;
        break;

    case SYM_ALPHA:
        SET_INTEGER(val, GOB_ALPHA(gob));
        break;

    case SYM_PANE:
        if (GOB_PANE(gob))
            Set_Block(val, Pane_To_Block(gob, 0, -1));
        else
            Set_Block(val, Make_Block(0));
        break;

    case SYM_PARENT:
        if (GOB_PARENT(gob)) {
            SET_GOB(val, GOB_PARENT(gob));
        }
        else
is_none:
            SET_NONE(val);
        break;

    case SYM_DATA:
        if (GOB_DTYPE(gob) == GOBD_OBJECT) {
            SET_OBJECT(val, GOB_DATA(gob));
        }
        else if (GOB_DTYPE(gob) == GOBD_BLOCK) {
            Set_Block(val, GOB_DATA(gob));
        }
        else if (GOB_DTYPE(gob) == GOBD_STRING) {
            Set_String(val, GOB_DATA(gob));
        }
        else if (GOB_DTYPE(gob) == GOBD_BINARY) {
            SET_BINARY(val, GOB_DATA(gob));
        }
        else if (GOB_DTYPE(gob) == GOBD_INTEGER) {
            SET_INTEGER(val, (REBIPT)GOB_DATA(gob));
        }
        else goto is_none;
        break;

    case SYM_FLAGS:
        Set_Block(val, Flags_To_Block(gob));
        break;

    default:
        return FALSE;
    }
    return TRUE;
}
예제 #4
0
파일: t-gob.c 프로젝트: xqlab/r3
*/	static void Insert_Gobs(REBGOB *gob, REBVAL *arg, REBCNT index, REBCNT len, REBFLG change)
/*
**		Insert one or more gobs into a pane at the given index.
**		If index >= tail, an append occurs. Each gob has its parent
**		gob field set. (Call Detach_Gobs() before inserting.)
**
***********************************************************************/
{
    REBGOB **ptr;
    REBCNT n, count;
    REBVAL *val, *sarg;
    REBINT i;

    // Verify they are gobs:
    sarg = arg;
    for (n = count = 0; n < len; n++, val++) {
        val = arg++;
        if (IS_WORD(val)) val = Get_Var(val);
        if (IS_GOB(val)) {
            count++;
            if (GOB_PARENT(VAL_GOB(val))) {
                // Check if inserting into same parent:
                i = -1;
                if (GOB_PARENT(VAL_GOB(val)) == gob) {
                    i = Find_Gob(gob, VAL_GOB(val));
                    if (i > 0 && i == (REBINT)index-1) { // a no-op
                        SET_GOB_STATE(VAL_GOB(val), GOBS_NEW);
                        return;
                    }
                }
                Detach_Gob(VAL_GOB(val));
                if ((REBINT)index > i) index--;
            }
        }
    }
    arg = sarg;

    // Create or expand the pane series:
    if (!GOB_PANE(gob)) {
        GOB_PANE(gob) = Make_Series(count, sizeof(REBGOB*), 0);
        LABEL_SERIES(GOB_PANE(gob), "gob pane");
        GOB_TAIL(gob) = count;
        index = 0;
    }
    else {
        if (change) {
            if (index + count > GOB_TAIL(gob)) {
                EXPAND_SERIES_TAIL(GOB_PANE(gob), index + count - GOB_TAIL(gob));
            }
        } else {
            Expand_Series(GOB_PANE(gob), index, count);
            if (index >= GOB_TAIL(gob)) index = GOB_TAIL(gob)-1;
        }
    }

    ptr = GOB_SKIP(gob, index);
    for (n = 0; n < len; n++) {
        val = arg++;
        if (IS_WORD(val)) val = Get_Var(val);
        if (IS_GOB(val)) {
            if GOB_PARENT(VAL_GOB(val)) Trap_Temp();
            *ptr++ = VAL_GOB(val);
            GOB_PARENT(VAL_GOB(val)) = gob;
            SET_GOB_STATE(VAL_GOB(val), GOBS_NEW);
        }
    }
}
예제 #5
0
*/ void rebcmp_compose(REBCMP_CTX* ctx, REBGOB* winGob, REBGOB* gob, REBOOL only)
/*
**	Compose content of the specified gob. Main compositing function.
**
**  If the ONLY arg is TRUE then the specified gob area will be
**  rendered to the buffer at 0x0 offset.(used by TO-IMAGE)
**
***********************************************************************/
{
	REBINT max_depth = 1000; // avoid infinite loops
	REBD32 abs_x = 0;
	REBD32 abs_y = 0;
	REBD32 abs_ox;
	REBD32 abs_oy;
	REBGOB* parent_gob = gob;
	REBINT x = GOB_LOG_X_INT(gob);
	REBINT y = GOB_LOG_Y_INT(gob);
	REBINT w = GOB_LOG_W_INT(gob);
	REBINT h = GOB_LOG_H_INT(gob);
	/*
	RL_Print("Composing gob: %x (%dx%d, %dx%d) in wingob %x\n", 
			 gob,
			 (int)GOB_LOG_X(gob),
			 (int)GOB_LOG_Y(gob),
			 GOB_W_INT(gob),
			 GOB_H_INT(gob),
			 winGob);
			 */

	//reset clip region to window area
	if (ctx->Win_Region != NULL){
		XDestroyRegion(ctx->Win_Region);
	}
	ctx->Win_Region = XCreateRegion();

	//calculate absolute offset of the gob
	while (GOB_PARENT(parent_gob) && (max_depth-- > 0) && !GET_GOB_FLAG(parent_gob, GOBF_WINDOW))
	{
		abs_x += GOB_LOG_X(parent_gob);
		abs_y += GOB_LOG_Y(parent_gob);
		parent_gob = GOB_PARENT(parent_gob);
	}

	assert(max_depth > 0);

	//the offset is shifted to render given gob at offset 0x0 (used by TO-IMAGE)
	if (only){
		ctx->absOffset.x = -abs_x;
		ctx->absOffset.y = -abs_y;
		abs_x = 0;
		abs_y = 0;
	} else {
		ctx->absOffset.x = 0;
		ctx->absOffset.y = 0;
	}

	ctx->New_Clip.x = abs_x;
	ctx->New_Clip.y = abs_y;
	ctx->New_Clip.width = GOB_LOG_W_INT(gob);
	ctx->New_Clip.height = GOB_LOG_H_INT(gob);

	//handle newly added gob case
	if (!GET_GOB_STATE(gob, GOBS_NEW)){
		//calculate absolute old offset of the gob
		abs_ox = abs_x + (GOB_XO(gob) - GOB_LOG_X(gob));
		abs_oy = abs_y + (GOB_YO(gob) - GOB_LOG_Y(gob));

		//set region with old gob location and dimensions
		ctx->Old_Clip.x = abs_ox;
		ctx->Old_Clip.y = abs_oy;
		ctx->Old_Clip.width = GOB_WO_INT(gob);
		ctx->Old_Clip.height = GOB_HO_INT(gob);
		XUnionRectWithRegion(&ctx->Old_Clip, ctx->Win_Region, ctx->Win_Region);
		//RL_Print("OLD: %dx%d %dx%d\n",(REBINT)abs_ox, (REBINT)abs_oy, (REBINT)abs_ox + GOB_WO_INT(gob), (REBINT)abs_oy + GOB_HO_INT(gob));
	}
	//RL_Print("NEW: %dx%d %dx%d\n",(REBINT)abs_x, (REBINT)abs_y, (REBINT)abs_x + GOB_LOG_W_INT(gob), (REBINT)abs_y + GOB_LOG_H_INT(gob));

	//Create union of "new" and "old" gob location
	XUnionRectWithRegion(&ctx->New_Clip, ctx->Win_Region, ctx->Win_Region);
	/*
	XClipBox(ctx->Win_Region, &win_rect);
	RL_Print("Old+New, %dx%d,%dx%d\n",
			 win_rect.x,
			 win_rect.y,
			 win_rect.x + win_rect.width,
			 win_rect.y + win_rect.height);
			 */

	if (!XEmptyRegion(ctx->Win_Region))
	{
		swap_buffer(ctx);
		ctx->Window_Buffer = rebcmp_get_buffer(ctx);
		if (gob == winGob) {
			memset(ctx->Window_Buffer, 0, ctx->pixbuf_len);
		}

		//redraw gobs
		process_gobs(ctx, winGob);

		rebcmp_release_buffer(ctx);

		ctx->Window_Buffer = NULL;
	}

	//update old GOB area
	GOB_XO(gob) = GOB_LOG_X(gob);
	GOB_YO(gob) = GOB_LOG_Y(gob);
	GOB_WO(gob) = GOB_LOG_W(gob);
	GOB_HO(gob) = GOB_LOG_H(gob);
}
예제 #6
0
파일: t-gob.c 프로젝트: Oldes/r3
*/	static REBFLG Get_GOB_Var(REBGOB *gob, REBVAL *word, REBVAL *val)
/*
***********************************************************************/
{
	REBSER *data;
	switch (VAL_WORD_CANON(word)) {

	case SYM_OFFSET:
		SET_PAIR(val, GOB_X(gob), GOB_Y(gob));
		break;

	case SYM_SIZE:
		SET_PAIR(val, GOB_W(gob), GOB_H(gob));
		break;

	case SYM_IMAGE:
		if (GOB_TYPE(gob) == GOBT_IMAGE) {
			// image
		}
		else goto is_none;
		break;

#ifdef HAS_WIDGET_GOB
	case SYM_WIDGET:
		data = VAL_SERIES(GOB_WIDGET_SPEC(gob));
		Init_Word(val, VAL_WORD_CANON(BLK_HEAD(data)));
		VAL_SET(val, REB_LIT_WORD);
		break;
#endif

	case SYM_DRAW:
		if (GOB_TYPE(gob) == GOBT_DRAW) {
			Set_Block(val, GOB_CONTENT(gob)); // Note: compiler optimizes SET_BLOCKs below
		}
		else goto is_none;
		break;

	case SYM_TEXT:
		if (GOB_TYPE(gob) == GOBT_TEXT) {
			Set_Block(val, GOB_CONTENT(gob));
		}
		else if (GOB_TYPE(gob) == GOBT_STRING) {
			Set_String(val, GOB_CONTENT(gob));
		}
		else goto is_none;
		break;

	case SYM_EFFECT:
		if (GOB_TYPE(gob) == GOBT_EFFECT) {
			Set_Block(val, GOB_CONTENT(gob));
		}
		else goto is_none;
		break;

	case SYM_COLOR:
		if (GOB_TYPE(gob) == GOBT_COLOR) {
			Set_Tuple_Pixel((REBYTE*)&GOB_CONTENT(gob), val);
		}
		else goto is_none;
		break;

	case SYM_ALPHA:
		SET_INTEGER(val, GOB_ALPHA(gob));
		break;

	case SYM_PANE:
		if (GOB_PANE(gob))
			Set_Block(val, Pane_To_Block(gob, 0, -1));
		else
			Set_Block(val, Make_Block(0));
		break;

	case SYM_PARENT:
		if (GOB_PARENT(gob)) {
			SET_GOB(val, GOB_PARENT(gob));
		}
		else
is_none:
			SET_NONE(val);
		break;

	case SYM_DATA:
#ifdef HAS_WIDGET_GOB
		if (GOB_TYPE(gob) == GOBT_WIDGET) {
			return OS_GET_WIDGET_DATA(gob, val);
		}
#endif
		data = GOB_DATA(gob);
		
		if (GOB_DTYPE(gob) == GOBD_OBJECT) {
			SET_OBJECT(val, data);
		}
		else if (GOB_DTYPE(gob) == GOBD_BLOCK) {
			Set_Block(val, data);
		}
		else if (GOB_DTYPE(gob) == GOBD_STRING) {
			Set_String(val, data);
		}
		else if (GOB_DTYPE(gob) == GOBD_BINARY) {
			SET_BINARY(val, data);
		}
		else if (GOB_DTYPE(gob) == GOBD_INTEGER) {
			SET_INTEGER(val, (REBIPT)data);
		}
		else goto is_none;
		break;

	case SYM_FLAGS:
		Set_Block(val, Flags_To_Block(gob));
		break;

	default:
		return FALSE;
	}
	return TRUE;
}
예제 #7
0
*/ void rebcmp_compose(REBCMP_CTX* ctx, REBGOB* winGob, REBGOB* gob, REBOOL only)
/*
**	Compose content of the specified gob. Main compositing function.
**
**  If the ONLY arg is TRUE then the specified gob area will be
**  rendered to the buffer at 0x0 offset.(used by TO-IMAGE)
**
***********************************************************************/
{
	REBINT max_depth = 1000; // avoid infinite loops
	REBD32 abs_x = 0;
	REBD32 abs_y = 0;
	REBD32 abs_ox;
	REBD32 abs_oy;
	REBGOB* parent_gob = gob;

	//reset clip region to window area
	//------------------------------
	//Put backend specific code here
	//------------------------------

	//calculate absolute offset of the gob
	while (GOB_PARENT(parent_gob) && (max_depth-- > 0) && !GET_GOB_FLAG(parent_gob, GOBF_WINDOW))
	{
		abs_x += GOB_LOG_X(parent_gob);
		abs_y += GOB_LOG_Y(parent_gob);
		parent_gob = GOB_PARENT(parent_gob);
	}

	//the offset is shifted to render given gob at offset 0x0 (used by TO-IMAGE)
	if (only){
		ctx->absOffset.x = -abs_x;
		ctx->absOffset.y = -abs_y;
		abs_x = 0;
		abs_y = 0;
	} else {
		ctx->absOffset.x = 0;
		ctx->absOffset.y = 0;
	}

	//handle newly added gob case
	if (!GET_GOB_STATE(gob, GOBS_NEW)){
		//calculate absolute old offset of the gob
		abs_ox = abs_x + (GOB_XO(gob) - GOB_LOG_X(gob));
		abs_oy = abs_y + (GOB_YO(gob) - GOB_LOG_Y(gob));

		//set region with old gob location and dimensions
		//------------------------------
		//Put backend specific code here
		//------------------------------
	}

	//Create union of "new" and "old" gob location
	REBOOL valid_intersection;
	//------------------------------
	//Put backend specific code here
	//------------------------------

	//intersect resulting region with window clip region
	//------------------------------
	//Put backend specific code here
	//------------------------------

	if (valid_intersection)
	{
		ctx->Window_Buffer = rebcmp_get_buffer(ctx);

		//redraw gobs
		process_gobs(ctx, winGob);

		rebcmp_release_buffer(ctx);

		ctx->Window_Buffer = NULL;
	}

	//update old GOB area
	GOB_XO(gob) = GOB_LOG_X(gob);
	GOB_YO(gob) = GOB_LOG_Y(gob);
	GOB_WO(gob) = GOB_LOG_W(gob);
	GOB_HO(gob) = GOB_LOG_H(gob);
}