cairo_bool_t _cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper, cairo_bool_t surface_is_unbounded, cairo_rectangle_int_t *extents) { cairo_rectangle_int_t clip; cairo_bool_t has_clip = FALSE; if (!surface_is_unbounded) has_clip = _cairo_surface_get_extents (wrapper->target, &clip); if (wrapper->clip) { if (has_clip) { if (! _cairo_rectangle_intersect (&clip, _cairo_clip_get_extents (wrapper->clip))) return FALSE; } else { has_clip = TRUE; clip = *_cairo_clip_get_extents (wrapper->clip); } } if (has_clip && wrapper->needs_transform) { cairo_matrix_t m; double x1, y1, x2, y2; _cairo_surface_wrapper_get_inverse_transform (wrapper, &m); x1 = clip.x; y1 = clip.y; x2 = clip.x + clip.width; y2 = clip.y + clip.height; _cairo_matrix_transform_bounding_box (&m, &x1, &y1, &x2, &y2, NULL); clip.x = floor (x1); clip.y = floor (y1); clip.width = ceil (x2) - clip.x; clip.height = ceil (y2) - clip.y; } if (has_clip) { if (wrapper->has_extents) { *extents = wrapper->extents; return _cairo_rectangle_intersect (extents, &clip); } else { *extents = clip; return TRUE; } } else if (wrapper->has_extents) { *extents = wrapper->extents; return TRUE; } else { _cairo_unbounded_rectangle_init (extents); return TRUE; } }
cairo_private void _cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t *matrix, cairo_box_t *bbox, cairo_bool_t *is_tight) { double x1, y1, x2, y2; _cairo_box_to_doubles (bbox, &x1, &y1, &x2, &y2); _cairo_matrix_transform_bounding_box (matrix, &x1, &y1, &x2, &y2, is_tight); _cairo_box_from_doubles (bbox, &x1, &y1, &x2, &y2); }
static int m_bounds(lua_State * L) { struct lobject_t * object = luaL_checkudata(L, 1, MT_OBJECT); double x1 = 0; double y1 = 0; double x2 = object->width; double y2 = object->height; _cairo_matrix_transform_bounding_box(&object->__transform_matrix, &x1, &y1, &x2, &y2, NULL); lua_pushnumber(L, x1); lua_pushnumber(L, y1); lua_pushnumber(L, x2 - x1); lua_pushnumber(L, y2 - y1); return 4; }
static int m_layout(lua_State * L) { struct lobject_t * object = luaL_checkudata(L, 1, MT_OBJECT); struct lobject_t * child = luaL_checkudata(L, 2, MT_OBJECT); double rx1 = luaL_optnumber(L, 3, 0); double ry1 = luaL_optnumber(L, 4, 0); double rx2 = luaL_optnumber(L, 5, object->width); double ry2 = luaL_optnumber(L, 6, object->height); if(child->alignment <= ALIGN_NONE) { } else if((child->alignment <= ALIGN_CENTER)) { double ox1 = rx1; double oy1 = ry1; double ox2 = rx2; double oy2 = ry2; double cx1 = 0; double cy1 = 0; double cx2 = child->width; double cy2 = child->height; _cairo_matrix_transform_bounding_box(__get_obj_matrix(child), &cx1, &cy1, &cx2, &cy2, NULL); switch(child->alignment) { case ALIGN_LEFT: __object_translate(child, ox1 - cx1, 0); rx1 += cx2 - cx1; break; case ALIGN_TOP: __object_translate(child, 0, oy1 - cy1); ry1 += cy2 - cy1; break; case ALIGN_RIGHT: __object_translate(child, ox2 - cx2, 0); rx2 -= cx2 - cx1; break; case ALIGN_BOTTOM: __object_translate(child, 0, oy2 - cy2); ry2 -= cy2 - cy1; break; case ALIGN_LEFT_TOP: __object_translate(child, ox1 - cx1, oy1 - cy1); rx1 += cx2 - cx1; ry1 += cy2 - cy1; break; case ALIGN_RIGHT_TOP: __object_translate(child, ox2 - cx2, oy1 - cy1); rx2 -= cx2 - cx1; ry1 += cy2 - cy1; break; case ALIGN_LEFT_BOTTOM: __object_translate(child, ox1 - cx1, oy2 - cy2); rx1 += cx2 - cx1; ry2 -= cy2 - cy1; break; case ALIGN_RIGHT_BOTTOM: __object_translate(child, ox2 - cx2, oy2 - cy2); rx2 -= cx2 - cx1; ry2 -= cy2 - cy1; break; case ALIGN_LEFT_CENTER: __object_translate(child, ox1 - cx1, oy1 - cy1 + ((oy2 - oy1) - (cy2 - cy1)) / 2); rx1 += cx2 - cx1; break; case ALIGN_TOP_CENTER: __object_translate(child, ox1 - cx1 + ((ox2 - ox1) - (cx2 - cx1)) / 2, oy1 - cy1); ry1 += cy2 - cy1; break; case ALIGN_RIGHT_CENTER: __object_translate(child, ox2 - cx2, oy1 - cy1 + ((oy2 - oy1) - (cy2 - cy1)) / 2); rx2 -= cx2 - cx1; break; case ALIGN_BOTTOM_CENTER: __object_translate(child, ox1 - cx1 + ((ox2 - ox1) - (cx2 - cx1)) / 2, oy2 - cy2); ry2 -= cy2 - cy1; break; case ALIGN_HORIZONTAL_CENTER: __object_translate(child, ox1 - cx1 + ((ox2 - ox1) - (cx2 - cx1)) / 2, 0); break; case ALIGN_VERTICAL_CENTER: __object_translate(child, 0, oy1 - cy1 + ((oy2 - oy1) - (cy2 - cy1)) / 2); break; case ALIGN_CENTER: __object_translate(child, ox1 - cx1 + ((ox2 - ox1) - (cx2 - cx1)) / 2, oy1 - cy1 + ((oy2 - oy1) - (cy2 - cy1)) / 2); break; default: break; } } else if((child->alignment <= ALIGN_CENTER_FILL)) { double w; double h; switch(child->alignment) { case ALIGN_LEFT_FILL: w = child->width * child->scalex; h = ry2 - ry1; __object_translate_fill(child, rx1, ry1, w, h); rx1 += w; break; case ALIGN_TOP_FILL: w = rx2 - rx1; h = child->height * child->scaley; __object_translate_fill(child, rx1, ry1, w, h); ry1 += h; break; case ALIGN_RIGHT_FILL: w = child->width * child->scalex; h = ry2 - ry1; __object_translate_fill(child, rx2 - w, ry1, w, h); rx2 -= w; break; case ALIGN_BOTTOM_FILL: w = rx2 - rx1; h = child->height * child->scaley; __object_translate_fill(child, rx1, ry2 - h, w, h); ry2 -= h; break; case ALIGN_HORIZONTAL_FILL: w = rx2 - rx1; h = child->height * child->scaley; __object_translate_fill(child, rx1, child->y, w, h); break; case ALIGN_VERTICAL_FILL: w = child->width * child->scalex; h = ry2 - ry1; __object_translate_fill(child, child->x, ry1, w, h); break; case ALIGN_CENTER_FILL: w = rx2 - rx1; h = ry2 - ry1; __object_translate_fill(child, rx1, ry1, w, h); rx1 += w; ry1 += h; break; default: break; } } lua_pushnumber(L, rx1); lua_pushnumber(L, ry1); lua_pushnumber(L, rx2); lua_pushnumber(L, ry2); return 4; }