Libcroco
|
00001 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ 00002 00003 /* 00004 * This file is part of The Croco Library 00005 * 00006 * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of version 2.1 of the 00010 * GNU Lesser General Public 00011 * License as published by the Free Software Foundation. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the 00019 * GNU Lesser General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00022 * USA 00023 */ 00024 00025 /* 00026 *$Id$ 00027 */ 00028 00029 #include <string.h> 00030 #include "cr-cascade.h" 00031 00032 #define PRIVATE(a_this) ((a_this)->priv) 00033 00034 struct _CRCascadePriv { 00035 /** 00036 *the 3 style sheets of the cascade: 00037 *author, user, and useragent sheet. 00038 *Intended to be addressed by 00039 *sheets[ORIGIN_AUTHOR] or sheets[ORIGIN_USER] 00040 *of sheets[ORIGIN_UA] ; 00041 */ 00042 CRStyleSheet *sheets[3]; 00043 guint ref_count; 00044 }; 00045 00046 /** 00047 * cr_cascade_new: 00048 *@a_author_sheet: the author origin style sheet. May be NULL. 00049 *@a_user_sheet: the user origin style sheet. May be NULL. 00050 *@a_ua_sheet: the user agent origin style sheet. May be NULL. 00051 * 00052 *Constructor of the #CRCascade class. 00053 *Note that all three parameters of this 00054 *method are ref counted and their refcount is increased. 00055 *Their refcount will be decreased at the destruction of 00056 *the instance of #CRCascade. 00057 *So the caller should not call their destructor. The caller 00058 *should call their ref/unref method instead if it wants 00059 * 00060 *Returns the newly built instance of CRCascade or NULL if 00061 *an error arose during constrution. 00062 */ 00063 CRCascade * 00064 cr_cascade_new (CRStyleSheet * a_author_sheet, 00065 CRStyleSheet * a_user_sheet, CRStyleSheet * a_ua_sheet) 00066 { 00067 CRCascade *result = NULL; 00068 00069 result = g_try_malloc (sizeof (CRCascade)); 00070 if (!result) { 00071 cr_utils_trace_info ("Out of memory"); 00072 return NULL; 00073 } 00074 memset (result, 0, sizeof (CRCascade)); 00075 00076 PRIVATE (result) = g_try_malloc (sizeof (CRCascadePriv)); 00077 if (!PRIVATE (result)) { 00078 cr_utils_trace_info ("Out of memory"); 00079 g_free (result); 00080 return NULL; 00081 } 00082 memset (PRIVATE (result), 0, sizeof (CRCascadePriv)); 00083 00084 if (a_author_sheet) { 00085 cr_cascade_set_sheet (result, a_author_sheet, ORIGIN_AUTHOR); 00086 } 00087 if (a_user_sheet) { 00088 cr_cascade_set_sheet (result, a_user_sheet, ORIGIN_USER); 00089 } 00090 if (a_ua_sheet) { 00091 cr_cascade_set_sheet (result, a_ua_sheet, ORIGIN_UA); 00092 } 00093 00094 return result; 00095 } 00096 00097 /** 00098 * cr_cascade_get_sheet: 00099 *@a_this: the current instance of #CRCascade. 00100 *@a_origin: the origin of the style sheet as 00101 *defined in the css2 spec in chapter 6.4. 00102 *Gets a given origin sheet. 00103 * 00104 *Gets a sheet, part of the cascade. 00105 *Note that the returned stylesheet 00106 *is refcounted so if the caller wants 00107 *to manage it's lifecycle, it must use 00108 *cr_stylesheet_ref()/cr_stylesheet_unref() instead 00109 *of the cr_stylesheet_destroy() method. 00110 *Returns the style sheet, or NULL if it does not 00111 *exist. 00112 */ 00113 CRStyleSheet * 00114 cr_cascade_get_sheet (CRCascade * a_this, enum CRStyleOrigin a_origin) 00115 { 00116 g_return_val_if_fail (a_this 00117 && a_origin >= ORIGIN_UA 00118 && a_origin < NB_ORIGINS, NULL); 00119 00120 return PRIVATE (a_this)->sheets[a_origin]; 00121 } 00122 00123 /** 00124 * cr_cascade_set_sheet: 00125 *@a_this: the current instance of #CRCascade. 00126 *@a_sheet: the stylesheet to set. 00127 *@a_origin: the origin of the stylesheet. 00128 * 00129 *Sets a stylesheet in the cascade 00130 * 00131 *Returns CR_OK upon successfull completion, an error 00132 *code otherwise. 00133 */ 00134 enum CRStatus 00135 cr_cascade_set_sheet (CRCascade * a_this, 00136 CRStyleSheet * a_sheet, enum CRStyleOrigin a_origin) 00137 { 00138 g_return_val_if_fail (a_this 00139 && a_sheet 00140 && a_origin >= ORIGIN_UA 00141 && a_origin < NB_ORIGINS, CR_BAD_PARAM_ERROR); 00142 00143 if (PRIVATE (a_this)->sheets[a_origin]) 00144 cr_stylesheet_unref (PRIVATE (a_this)->sheets[a_origin]); 00145 PRIVATE (a_this)->sheets[a_origin] = a_sheet; 00146 cr_stylesheet_ref (a_sheet); 00147 a_sheet->origin = a_origin; 00148 return CR_OK; 00149 } 00150 00151 /** 00152 *cr_cascade_ref: 00153 *@a_this: the current instance of #CRCascade 00154 * 00155 *Increases the reference counter of the current instance 00156 *of #CRCascade. 00157 */ 00158 void 00159 cr_cascade_ref (CRCascade * a_this) 00160 { 00161 g_return_if_fail (a_this && PRIVATE (a_this)); 00162 00163 PRIVATE (a_this)->ref_count++; 00164 } 00165 00166 /** 00167 * cr_cascade_unref: 00168 *@a_this: the current instance of 00169 *#CRCascade. 00170 * 00171 *Decrements the reference counter associated 00172 *to this instance of #CRCascade. If the reference 00173 *counter reaches zero, the instance is destroyed 00174 *using cr_cascade_destroy() 00175 */ 00176 void 00177 cr_cascade_unref (CRCascade * a_this) 00178 { 00179 g_return_if_fail (a_this && PRIVATE (a_this)); 00180 00181 if (PRIVATE (a_this)->ref_count) 00182 PRIVATE (a_this)->ref_count--; 00183 if (!PRIVATE (a_this)->ref_count) { 00184 cr_cascade_destroy (a_this); 00185 } 00186 } 00187 00188 /** 00189 * cr_cascade_destroy: 00190 * @a_this: the current instance of #CRCascade 00191 * 00192 * Destructor of #CRCascade. 00193 */ 00194 void 00195 cr_cascade_destroy (CRCascade * a_this) 00196 { 00197 g_return_if_fail (a_this); 00198 00199 if (PRIVATE (a_this)) { 00200 gulong i = 0; 00201 00202 for (i = 0; PRIVATE (a_this)->sheets && i < NB_ORIGINS; i++) { 00203 if (PRIVATE (a_this)->sheets[i]) { 00204 if (cr_stylesheet_unref 00205 (PRIVATE (a_this)->sheets[i]) 00206 == TRUE) { 00207 PRIVATE (a_this)->sheets[i] = NULL; 00208 } 00209 } 00210 } 00211 g_free (PRIVATE (a_this)); 00212 PRIVATE (a_this) = NULL; 00213 } 00214 g_free (a_this); 00215 }