/**
                                                                          
	@file:	r2d.h	
	
	@author Christophe Favergeon                              
                                                                          
    @version	1.0	

    Purpose:	Riviera 2D : Public API       
	
*/

/*
																			
 	Date       	Modification												
  ------------------------------------									
    06/02/2001	Create		
	10/18/2001  Version 0.5 for first integration with Riviera database
	04/30/2002  Version 1.0
																											    
																			
 (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved
*/

/*
  History       

  Apr-06-2005 MMI-SPR-29655 - xreddymn
  Added function r2d_flush_region to allow flushing of portions 
  of framebuffer to the display

*/


#ifndef __R2D_H_
#define __R2D_H_

#include "rv/general.h"
#include "rvf/rvf_api.h"
#include "r2d/r2d_config.h"


/***************************************

    IMPORTANT NOTES

***************************************/

// For speed reasons the system is minimizing
// number of checks.

// So, the user must ensure that some
// conditions are respected before she/he
// calls the drawing subroutines :

// For rectangle, ellipse etc... one must
// has : br_x > ul_x and br_y > ul_y

// Rectangles and ellipse where one of
// the dimensions is 0 are not allowed

// For circle, the radius must be strictly
// positive



/***************************************

    TYPES / CONSTANTS

***************************************/

////////////////////////////////////////
//
// GENERAL
//

typedef enum K_R2D_ERROR
{
	R2D_OK=0,
	R2D_MEMORY_ERR=-4,
	R2D_UNKNOWN_OP=-5,
	R2D_LOCK_ERROR=-6,
	R2D_UNLOCK_ERROR=-7
} T_R2D_ERROR;

////////////////////////////////////////
//
// Memory
//
typedef void *T_R2D_REFCOUNT_PTR;

// Should NEVER be allocated on stack
typedef struct R2D_REFCOUNTING
{
  // Refcounting
     INT16 refcount;
} T_R2D_REFCOUNT;


////////////////////////////////////////
//
// Framebuffer
//
typedef enum {R2D_LCD_KIND=1, R2D_FULL_KIND} T_R2D_FRAMEBUFFER_KIND;

typedef void *T_R2D_FRAMEBUFFER_PTR;


////////////////////////////////////////
//
// Graphic context
//
typedef void *T_R2D_GC_PTR;

typedef enum K_R2D_DRAWING_MODE {
R2D_COPY_MODE=0,
R2D_OR_MODE,
R2D_AND_MODE,
R2D_XOR_MODE,
R2D_NOT_COPY_MODE,
R2D_NOT_OR_MODE,
R2D_NOT_AND_MODE,
R2D_NOT_XOR_MODE,
R2D_ALPHA_MODE,
R2D_ERASE_MODE
} T_R2D_DRAWING_MODE ;

typedef enum K_R2D_COLOR_REF
{
R2D_RED=1,
R2D_BLUE,
R2D_GREEN,
R2D_WHITE,
R2D_BLACK,
R2D_GRAY50
} T_R2D_COLOR_REF;

typedef enum K_R2D_TEXT_FACE
{
R2D_SYSTEM=1,
R2D_TYPEWRITER,
R2D_PROPORTIONAL
} T_R2D_TEXT_FACE;

typedef enum K_R2D_TEXT_STYLE
{
R2D_PLAIN=1,
R2D_BOLD=2,
R2D_ITALIC=4,
R2D_UNDERLINED=8,
R2D_STRIKETHROUGH=16
} T_R2D_TEXT_STYLE;

typedef enum K_R2D_TEXT_SIZE
{
R2D_SMALL=1,
R2D_MEDIUM,
R2D_LARGE
} T_R2D_TEXT_SIZE ;

typedef enum K_R2D_SCRIPT_MODE
{
R2D_LEFT_TO_RIGHT=1,
R2D_RIGHT_TO_LEFT=2
} T_R2D_SCRIPT_MODE ;


////////////////////////////////////////
//
// Shapes
//
typedef void *T_R2D_SHAPE_PTR;

typedef struct R2D_R
{
  INT16 refcount;
  void *p_r2d_class;
  INT16 ul_x,ul_y,br_x,br_y;
} T_R2D_RECT;

////////////////////////////////////////
//
// Text
//
typedef UINT16 T_R2D_UTF16;
typedef UINT32* T_R2D_CHAR_METRIC_PTR;

////////////////////////////////////////
//
// Color
//
typedef UINT32 T_R2D_ARGB_COLOR;

////////////////////////////////////////
//
// Textures
//
typedef void *T_R2D_FREE_TEXTURE_PTR;
typedef void *T_R2D_ANCHORED_TEXTURE_PTR;


/***************************************

    Functions

***************************************/

////////////////////////////////////////
//
// Memory
//

// Increment refcount of an object
#define r2d_retain(p) {\
    if (p) \
    { \
	   if (((T_R2D_REFCOUNT*)(p))->refcount>0) \
         ((T_R2D_REFCOUNT*)(p))->refcount++; \
    \
    } \
   }

////////////////////////////////////////
//
// Texture
//

// The pattern is an array of ARGB colors saved column per column
T_R2D_FREE_TEXTURE_PTR r2d_new_free_texture(T_RVF_MB_ID bank,INT16 size,T_R2D_ARGB_COLOR *pattern);
T_R2D_FREE_TEXTURE_PTR r2d_new_const_free_texture(T_RVF_MB_ID bank,INT16 size,T_R2D_ARGB_COLOR *pattern);

T_R2D_ANCHORED_TEXTURE_PTR r2d_new_anchored_texture(T_RVF_MB_ID bank,T_R2D_GC_PTR gc,T_R2D_FREE_TEXTURE_PTR texture);

void              r2d_release_free_texture(T_R2D_FREE_TEXTURE_PTR texture);
void			  r2d_release_anchored_texture(T_R2D_ANCHORED_TEXTURE_PTR texture);

////////////////////////////////////////
//
// Framebuffer
//


T_R2D_FRAMEBUFFER_PTR r2d_new_framebuffer(T_RVF_MB_ID bank,T_R2D_FRAMEBUFFER_KIND the_kind,UINT16 width, UINT16 height);
void                  r2d_release_framebuffer(T_R2D_FRAMEBUFFER_PTR the_framebuffer);

// return the size used in a memory bank by a framebuffer
UINT32 r2d_get_framebuffer_size(T_R2D_FRAMEBUFFER_KIND the_kind,UINT16 width, UINT16 height);

////////////////////////////////////////
//
// Graphic context
//

// Return a new graphical contect connected to the LCD framebuffer
// (The LCD framebuffer is private)
T_R2D_GC_PTR   r2d_new_lcd_context(T_RVF_MB_ID bank);

// Return a new graphical context connected to a framebuffer
T_R2D_GC_PTR   r2d_new_context(T_RVF_MB_ID bank,T_R2D_FRAMEBUFFER_PTR the_frame_buffer);

// Return size used in a memory bank by a graphical context (not taking 
// into account the framebuffer used by this context)
// For LCD context, the LCD framebuffer is created at build time and
// does not take any space in any memory bank. Other framebuffers are
// using memory from the memory bank
UINT32 r2d_get_gc_size(void);

// Return a graphical context for a picture saved in R2D format
T_R2D_GC_PTR r2d_new_picture_context(T_RVF_MB_ID bank,const UINT32 *the_picture,T_R2D_FRAMEBUFFER_KIND kind);
void         r2d_release_picture_context(T_R2D_GC_PTR gc);

// Release a graphical context. 
// For LCD, the framebuffer is released but never deleted
// since it is also owned by the R2D software entity
void           r2d_release_context(T_R2D_GC_PTR gc);

// Clear the content of the framebuffer referenced by 
// the graphic context (in white);
void           r2d_erase(T_R2D_GC_PTR gc);
void           r2d_erase_with_background(T_R2D_GC_PTR gc,
										 INT16 a,INT16 b,
										 INT16 c,INT16 d);

// Get size and width of the drawing area of the framebuffer referenced
// by the graphic context. The framebuffer (as a memory area) is generally
// a bit larger than the drawing area (defined by width*height) because
// of memory alignment constraints
UINT16          r2d_get_width(T_R2D_GC_PTR gc);
UINT16          r2d_get_height(T_R2D_GC_PTR gc);

void            r2d_get_pen_pos(T_R2D_GC_PTR gc,INT16 *x,INT16 *y);

//
// Drawing mode settings
T_R2D_DRAWING_MODE r2d_get_drawing_mode(T_R2D_GC_PTR gc);
T_R2D_ERROR               r2d_set_drawing_mode(T_R2D_GC_PTR gc,T_R2D_DRAWING_MODE the_mode);

UINT16          r2d_get_pen_size(T_R2D_GC_PTR gc);
void           r2d_set_pen_size(T_R2D_GC_PTR gc,UINT16 the_size);

BOOLEAN        r2d_dash_enabled(T_R2D_GC_PTR gc);
void           r2d_set_dash_state(T_R2D_GC_PTR gc,BOOLEAN enabled);

// Get or set the coordinates of the origin of the framebuffer in the
// graphic context (upper-left point)
// Clipping shape does not move when origin coordinates are
// changed. It is always at the same position relatively to the
// framebuffer
void           r2d_set_context_origin(T_R2D_GC_PTR gc,INT16 x,INT16 y);
void           r2d_get_context_origin(T_R2D_GC_PTR gc,INT16 *x,INT16 *y);

// Convert coordinates such that the framebuffer origin is (0,0)
// after the transform
void           r2d_local_to_global(T_R2D_GC_PTR gc,INT16 *x,INT16 *y);

//
// Text settings
void           r2d_set_text_face(T_R2D_GC_PTR gc,T_R2D_TEXT_FACE the_face);
T_R2D_TEXT_FACE r2d_get_text_face(T_R2D_GC_PTR gc);

void           r2d_set_text_style(T_R2D_GC_PTR gc,T_R2D_TEXT_STYLE the_style);
T_R2D_TEXT_STYLE r2d_get_text_style(T_R2D_GC_PTR gc);

void           r2d_set_text_size(T_R2D_GC_PTR gc,T_R2D_TEXT_SIZE the_size);
T_R2D_TEXT_SIZE r2d_get_text_size(T_R2D_GC_PTR gc);

T_R2D_ERROR r2d_context_lock(T_R2D_GC_PTR gc);
T_R2D_ERROR r2d_context_unlock(T_R2D_GC_PTR gc);

// Flush lcd framebuffer to force the display
void           r2d_flush(void);

// xreddymn Apr-06-2005 MMI-SPR-29655: Function to flush a region to display
void           r2d_flush_region(INT16 ul_x,INT16 ul_y,INT16 br_x,INT16 br_y);

void           r2d_disable_refresh(void);
void           r2d_enable_refresh(void);


// Return the a pointer to the memory area containing
// pixels for the graphic context gc
// Use with care
UINT32*        r2d_get_pixmap(T_R2D_GC_PTR gc);

////////////////////////////////////////
//
// Colors
//

// (Never assume a particular format for the ARGB field
// and use Riviera functions to create/set/get colors)

// Get ARGB foreground color
T_R2D_ARGB_COLOR         r2d_get_foreground_color(T_R2D_GC_PTR gc);

// Set foreground color (seperate components or packed format as
// returned by the Riviera 2D API) 
void           r2d_set_foreground_color_with_argb(T_R2D_GC_PTR gc,UINT16 alpha,UINT16 red,
               UINT16 green,UINT16 blue);
void           r2d_set_foreground_color(T_R2D_GC_PTR gc,T_R2D_ARGB_COLOR color);

// Get ARGB background color
T_R2D_ARGB_COLOR         r2d_get_background_color(T_R2D_GC_PTR gc);

// Set ARGB background color
// ("A" field not supported in that version)
void           r2d_set_background_color_with_argb(T_R2D_GC_PTR gc,UINT16 alpha,UINT16 red,
               UINT16 green,UINT16 blue);
void           r2d_set_background_color(T_R2D_GC_PTR gc,T_R2D_ARGB_COLOR color);

// Set background texture
// (it hides temporarily the background color)
void           r2d_set_background_texture(T_R2D_GC_PTR gc,T_R2D_ANCHORED_TEXTURE_PTR texture);
T_R2D_ANCHORED_TEXTURE_PTR  r2d_get_background_texture(T_R2D_GC_PTR gc);


// Get color components from an ARGB color
#define        r2d_alpha(color) ((UINT16)(((color & 0x0FF000000) >> 24)))
#define        r2d_red(color) ((UINT16)(((color & 0x0FF0000) >> 16)))
#define        r2d_green(color) ((UINT16)(((color & 0x0FF00) >> 8)))
#define        r2d_blue(color) ((UINT16)(((color & 0x00FF))))

T_R2D_ARGB_COLOR         r2d_new_argb_color(UINT16 alpha,UINT16 red,UINT16 green,UINT16 blue);

T_R2D_ARGB_COLOR         r2d_get_argb_color_at_point(T_R2D_GC_PTR gc,INT16 x,INT16 y);
T_R2D_ARGB_COLOR         r2d_get_standard_argb_color(T_R2D_COLOR_REF ref);
void                     r2d_hsv_to_rgb( INT16 *r, INT16 *g, INT16 *b, INT32 h, INT32 s, INT32 v );

////////////////////////////////////////
//
// Shape functions
//

void r2d_draw_shape(T_R2D_SHAPE_PTR self,T_R2D_GC_PTR gc);
void r2d_fill_shape(T_R2D_SHAPE_PTR self,T_R2D_GC_PTR gc);
void r2d_translate_shape(T_R2D_SHAPE_PTR self,INT16 dx,INT16 dy);
void r2d_release_shape(T_R2D_SHAPE_PTR self);
T_R2D_SHAPE_PTR r2d_clone_shape(T_RVF_MB_ID bank,T_R2D_SHAPE_PTR self);


T_R2D_SHAPE_PTR r2d_new_rectangle(T_RVF_MB_ID bank,INT16 ul_x,INT16 ul_y,INT16 br_x,INT16 br_y);
T_R2D_SHAPE_PTR r2d_new_circle(T_RVF_MB_ID bank,INT16 x,INT16 y,INT16 r);
T_R2D_SHAPE_PTR r2d_new_ellipse(T_RVF_MB_ID bank,INT16 ul_x,INT16 ul_y,INT16 br_x,INT16 br_y);
T_R2D_SHAPE_PTR r2d_new_round_rectangle(T_RVF_MB_ID bank,INT16 ul_x,INT16 ul_y,
                                         INT16 br_x,INT16 br_y,INT16 h,INT16 v);

T_R2D_SHAPE_PTR r2d_new_arc(T_RVF_MB_ID bank,INT16 start_angle, INT16 stop_angle,INT16 ul_x,INT16 ul_y,
                                         INT16 br_x,INT16 br_y);

T_R2D_SHAPE_PTR r2d_new_text(T_RVF_MB_ID bank,INT16 x, INT16 y,T_R2D_UTF16 *the_text);

T_R2D_SHAPE_PTR r2d_new_rectangle_intersection(T_RVF_MB_ID bank,T_R2D_SHAPE_PTR a,T_R2D_SHAPE_PTR b);
T_R2D_SHAPE_PTR r2d_new_rectangle_union(T_RVF_MB_ID bank,T_R2D_SHAPE_PTR a,T_R2D_SHAPE_PTR b);

#define r2d_get_xmin(r) ((INT16)(((T_R2D_RECT*)r)->ul_x))
#define r2d_get_ymin(r) ((INT16)(((T_R2D_RECT*)r)->ul_y))
#define r2d_get_xmax(r) ((INT16)(((T_R2D_RECT*)r)->br_x))
#define r2d_get_ymax(r) ((INT16)(((T_R2D_RECT*)r)->br_y))
#define r2d_get_shape_width(r) (((INT16)(((T_R2D_RECT*)r)->br_x)) - ((INT16)(((T_R2D_RECT*)r)->ul_x)))
#define r2d_get_shape_height(r) (((INT16)(((T_R2D_RECT*)r)->br_y)) - ((INT16)(((T_R2D_RECT*)r)->ul_y)))

////////////////////////////////////////
//
// Clipping functions
//

// For clipping with rectangle, we stop
// before xmax (at xmax-1)
// contrary to rectangle drawing where xmax is drawn
void r2d_set_clipping_shape(T_R2D_SHAPE_PTR self,T_R2D_GC_PTR gc);
T_R2D_SHAPE_PTR r2d_get_clipping_shape(T_R2D_GC_PTR gc);
T_R2D_ERROR r2d_restore_standard_clipping_shape(T_R2D_GC_PTR gc);

////////////////////////////////////////
//
// Test functions
//
BOOLEAN r2d_point_in_shape(T_R2D_SHAPE_PTR r,INT16 x,INT16 y);

///////////////////////////////////////
//
// Drawing functions
//

// Draw a point in graphical context gc at position (x, y)
void           r2d_draw_point(T_R2D_GC_PTR gc,INT16 x,INT16 y);
void           r2d_erase_point(T_R2D_GC_PTR gc,INT16 x,INT16 y);

// Move pen to point (x,y)
void           r2d_moveto(T_R2D_GC_PTR gc,INT16 x,INT16 y);
// draw line from pen position to point (x,y)
// (Last point at (x,y) is NOT drawn since x,y is the ending
//  coordinate and not the ending point)
void           r2d_lineto(T_R2D_GC_PTR gc,INT16 x,INT16 y);

// br means bottom right as displayed on screen but
// br has a higher y coordinate than ul
// since y increasing means below

// Rectangle
void           r2d_draw_rectangle(T_R2D_GC_PTR gc,
                  INT16 ul_x,INT16 ul_y,INT16 bl_x, INT16 bl_y);
void           r2d_fill_rectangle(T_R2D_GC_PTR gc,
                  INT16 ul_x,INT16 ul_y,INT16 br_x, INT16 br_y);

// Circle
void           r2d_draw_circle(T_R2D_GC_PTR gc,
                 INT16 x,INT16 y,INT16 r);
void           r2d_fill_circle(T_R2D_GC_PTR gc,
                 INT16 x,INT16 y,INT16 r);

// Ellipse
void           r2d_draw_ellipse(T_R2D_GC_PTR gc,
                  INT16 ul_x,INT16 ul_y,INT16 bl_x, INT16 bl_y);
void           r2d_fill_ellipse(T_R2D_GC_PTR gc,
                  INT16 ul_x,INT16 ul_y,INT16 bl_x, INT16 bl_y);


// Round Rectangle
void           r2d_draw_round_rectangle(T_R2D_GC_PTR gc,
                  INT16 ul_x,INT16 ul_y,INT16 bl_x, INT16 bl_y,INT16 h,INT16 v);
void           r2d_fill_round_rectangle(T_R2D_GC_PTR gc,
                  INT16 ul_x,INT16 ul_y,INT16 bl_x, INT16 bl_y,INT16 h,INT16 v);

// Ellipse arc

void           r2d_draw_arc(T_R2D_GC_PTR gc,INT16 start_angle,INT16 stop_angle,
                  INT16 ul_x,INT16 ul_y,INT16 bl_x,INT16 bl_y);
void           r2d_fill_arc(T_R2D_GC_PTR gc, INT16 start_angle,INT16 stop_angle,
                  INT16 ul_x,INT16 ul_y,INT16 bl_x, INT16 bl_y);

///////////////////////////////////////
//
// Copy function
//

T_R2D_ERROR           r2d_blit_rect(T_R2D_GC_PTR src_gc,T_R2D_GC_PTR dst_gc,
                             T_R2D_SHAPE_PTR src_rectangle, 
							 T_R2D_SHAPE_PTR dst_rectangle,
							 BOOLEAN use_foreground_color);



///////////////////////////////////////
//
// Text functions
//

#define r2d_get_char_width(p) (((INT32*)p)[1])
#define r2d_get_char_height(p) (((INT32*)p)[2])
#define r2d_get_char_dx(p) (((INT32*)p)[3])
#define r2d_get_char_dy(p) (((INT32*)p)[4])
#define r2d_get_char_org_x(p) (((INT32*)p)[5])
#define r2d_get_char_org_y(p) (((INT32*)p)[6])

// Return nb of word16 (a Glyph may be made of more than one Unicode char
// so from more than one word16. Consequently, it does not represent the number
// or displayed chars)
INT16 r2d_str_nb_word16(T_R2D_UTF16 *l);
T_R2D_UTF16 *r2d_duplicate_text(T_RVF_MB_ID bank,T_R2D_UTF16 *l);

T_R2D_UTF16 *r2d_new_unicode_from_cstring(T_RVF_MB_ID bank,unsigned char *the_string);
T_R2D_UTF16 *r2d_new_unicode_from_pstring(T_RVF_MB_ID bank,unsigned char *the_string);

T_R2D_CHAR_METRIC_PTR r2d_get_char_metrics(T_R2D_GC_PTR gc,UINT32 the_char);

UINT32 r2d_get_next_char(T_R2D_UTF16 *the_text,INT16 *pos,
					     UINT16 max_chars,BOOLEAN *swapping);


T_R2D_ERROR r2d_draw_char(T_R2D_GC_PTR font_cache_gc,
                    T_R2D_GC_PTR gc,
                    T_R2D_GC_PTR fontgc,
                    INT16 x,INT16 y,INT16 org_size,T_R2D_CHAR_METRIC_PTR p);

T_R2D_ERROR   r2d_draw_text(T_R2D_GC_PTR gc,INT16 x,INT16 y,T_R2D_UTF16 *the_text);

// Length is given in word16
T_R2D_ERROR   r2d_draw_chars(T_R2D_GC_PTR gc,INT16 x,INT16 y,T_R2D_UTF16 *the_text,
							 UINT16 nb_words16);

T_R2D_ERROR   r2d_get_text_width(T_R2D_GC_PTR gc,T_R2D_UTF16 *the_text,UINT16 *size);

// Length is given in word16
T_R2D_ERROR   r2d_get_width_of_chars(T_R2D_GC_PTR gc,T_R2D_UTF16 *the_text,UINT16 nb_words16,UINT16 *size);


void          r2d_get_font_info(T_R2D_GC_PTR gc,INT16 *ascent,INT16 *descent,INT16 *leading);

T_R2D_SCRIPT_MODE r2d_get_script_mode(T_R2D_GC_PTR gc);
void r2d_set_script_mode(T_R2D_GC_PTR gc,T_R2D_SCRIPT_MODE mode);

///////////////////////////////////////
//
// Globals
//

#define R2D_EMPTY_RECT NULL
extern T_R2D_GC_PTR r2d_g_lcd_gc;
extern INT16 r2d_g_refresh_disabled;

#endif
