/* Face data structures.
   Copyright (C) 1995 Board of Trustees, University of Illinois
   Copyright (C) 1995 Ben Wing

This file is part of XEmacs.

XEmacs is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

XEmacs is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with XEmacs; see the file COPYING.  If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Synched up with: Not in FSF. */

#ifndef _XEMACS_FACES_H_
#define _XEMACS_FACES_H_

#include "dynarr.h"

struct Lisp_Face
{
  struct lcrecord_header header;

  Lisp_Object name;
  Lisp_Object doc_string;
  unsigned int dirty :1;

  Lisp_Object foreground;
  Lisp_Object background;
  Lisp_Object font;

  Lisp_Object display_table;
  Lisp_Object background_pixmap;

  Lisp_Object underline;
  Lisp_Object highlight;
  Lisp_Object dim;
  Lisp_Object blinking;
  Lisp_Object reverse;

  Lisp_Object plist;
};

struct face_cache_element
{
  Lisp_Object face;

  Lisp_Object foreground;
  Lisp_Object background;
  Lisp_Object font;
  Lisp_Object display_table;
  Lisp_Object background_pixmap;

  unsigned int dirty :1;
  unsigned int updated :1;

  unsigned int underline :1;
  unsigned int highlight :1;
  unsigned int dim :1;
  unsigned int blinking :1;
  unsigned int reverse :1;

  /* Used when merging to tell if the above field represents an actual
     value of this face or a fallback value. */
  unsigned int foreground_specified :1;
  unsigned int background_specified :1;
  unsigned int font_specified :1;
  unsigned int display_table_specified :1;
  unsigned int background_pixmap_specified :1;

  unsigned int underline_specified :1;
  unsigned int highlight_specified :1;
  unsigned int dim_specified :1;
  unsigned int blinking_specified :1;
  unsigned int reverse_specified :1;
};

DECLARE_LRECORD (face, struct Lisp_Face);
#define XFACE(x) XRECORD (x, face, struct Lisp_Face)
#define XSETFACE(x, p) XSETRECORD (x, p, face)
#define FACEP(x) RECORDP (x, face)
#define CHECK_FACE(x, i) CHECK_RECORD (x, face)

extern void mark_face_cache_elements (face_cache_element_dynarr *elements,
				      void (*markobj) (Lisp_Object));
extern void mark_face_cache_elements_as_clean (struct window *w);
extern void mark_face_cache_elements_as_not_updated (struct window *w);
extern void reset_face_cache_elements (struct window *w);
extern face_index get_builtin_face_cache_index (struct window *w,
						Lisp_Object face);

extern void mark_all_faces_as_clean (void);
extern void init_frame_faces (struct frame *f);
extern void init_device_faces (struct device *d);
extern void init_global_faces (struct device *d);
extern face_index
get_extent_fragment_face_cache_index (struct window *w,
				      struct extent_fragment *ef,
				      struct extent *dummy_lhe_extent);
extern Lisp_Object Ffind_face (Lisp_Object face_or_name);
extern Lisp_Object Fget_face (Lisp_Object face_or_name);
extern void update_frame_face_values (struct frame *f);
extern void face_property_was_changed (Lisp_Object face, Lisp_Object property,
				       Lisp_Object locale);
extern void face_font_metric_info (Lisp_Object face, Lisp_Object domain,
				   struct font_metric_info *fm);
extern void default_face_height_and_width (Lisp_Object domain,
				           int *height, int *width);

extern Lisp_Object Qforeground, Qbackground, Qfont, Qdisplay_table;
extern Lisp_Object Qbackground_pixmap, Qunderline, Qhighlight, Qdim;
extern Lisp_Object Qblinking, Qreverse;

extern Lisp_Object Vdefault_face, Vmodeline_face, Vhighlight_face;
extern Lisp_Object Vleft_margin_face, Vright_margin_face;

#define FACE_CACHE_ELEMENT_FACE(window, index)				\
  Dynarr_atp (window->face_cache_elements, index)->face
#define FACE_CACHE_ELEMENT_FOREGROUND(window, index)			\
  Dynarr_atp (window->face_cache_elements, index)->foreground
#define FACE_CACHE_ELEMENT_BACKGROUND(window, index)			\
  Dynarr_atp (window->face_cache_elements, index)->background
/* #### This can be referenced by the font_metric_info device method,
   but face_cache_elements isn't initialized for the stream device.
   Since it doesn't need the value we just return nil here to avoid
   blowing up in multiple places. */
#define FACE_CACHE_ELEMENT_FONT(window, index)				\
  ((window)->face_cache_elements					\
   ? Dynarr_atp (window->face_cache_elements, index)->font		\
   : Qnil)
#define FACE_CACHE_ELEMENT_DISPLAY_TABLE(window, index)			\
  Dynarr_atp (window->face_cache_elements, index)->display_table
#define FACE_CACHE_ELEMENT_BACKGROUND_PIXMAP(window, index)		\
  Dynarr_atp (window->face_cache_elements, index)->background_pixmap
#define FACE_CACHE_ELEMENT_DIRTY(window, index)				\
  Dynarr_atp (window->face_cache_elements, index)->dirty
#define FACE_CACHE_ELEMENT_UNDERLINE_P(window, index)			\
  Dynarr_atp (window->face_cache_elements, index)->underline
#define FACE_CACHE_ELEMENT_HIGHLIGHT_P(window, index)			\
  Dynarr_atp (window->face_cache_elements, index)->highlight
#define FACE_CACHE_ELEMENT_DIM_P(window, index)				\
  Dynarr_atp (window->face_cache_elements, index)->dim
#define FACE_CACHE_ELEMENT_BLINKING_P(window, index)			\
  Dynarr_atp (window->face_cache_elements, index)->blinking
#define FACE_CACHE_ELEMENT_REVERSE_P(window, index)			\
  Dynarr_atp (window->face_cache_elements, index)->reverse

#define FACE_PROPERTY_INSTANCE(face, property, domain, no_fallback)	\
  specifier_instance_no_quit (Fget (face, property, Qnil), domain,	\
			      no_fallback)
#define FACE_PROPERTY_SPEC_LIST(face, property, locale)			\
  Fspecifier_spec_list (Fget (face, property, Qnil), locale, Qnil, Qnil)
#define SET_FACE_PROPERTY(face, property, locale, value, tag, how_to_add) \
  Fadd_spec_to_specifier (Fget (face, property, Qnil),			  \
			  locale, value, tag, how_to_add)

#define FACE_FOREGROUND(face, domain)					\
  FACE_PROPERTY_INSTANCE (face, Qforeground, domain, 0)
#define FACE_BACKGROUND(face, domain)					\
  FACE_PROPERTY_INSTANCE (face, Qbackground, domain, 0)
#define FACE_FONT(face, domain)						\
  FACE_PROPERTY_INSTANCE (face, Qfont, domain, 0)
#define FACE_DISPLAY_TABLE(face, domain)				\
  FACE_PROPERTY_INSTANCE (face, Qdisplay_table, domain, 0)
#define FACE_BACKGROUND_PIXMAP(face, domain)				\
  FACE_PROPERTY_INSTANCE (face, Qbackground_pixmap, domain, 0)
#define FACE_UNDERLINE_P(face, domain)					\
  FACE_PROPERTY_INSTANCE (face, Qunderline_p, domain, 0)
#define FACE_HIGHLIGHT_P(face, domain)					\
  FACE_PROPERTY_INSTANCE (face, Qhighlight_p, domain, 0)
#define FACE_DIM_P(face, domain)					\
  FACE_PROPERTY_INSTANCE (face, Qdim_p, domain, 0)
#define FACE_BLINKING_P(face, domain)					\
  FACE_PROPERTY_INSTANCE (face, Qblinking_p, domain, 0)
#define FACE_REVERSE_P(face, domain)					\
  FACE_PROPERTY_INSTANCE (face, Qreverse_p, domain, 0)

#endif /* _XEMACS_FACES_H_ */
