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 return NULL; 00080 } 00081 memset (PRIVATE (result), 0, sizeof (CRCascadePriv)); 00082 00083 if (a_author_sheet) { 00084 cr_cascade_set_sheet (result, a_author_sheet, ORIGIN_AUTHOR); 00085 } 00086 if (a_user_sheet) { 00087 cr_cascade_set_sheet (result, a_user_sheet, ORIGIN_USER); 00088 } 00089 if (a_ua_sheet) { 00090 cr_cascade_set_sheet (result, a_ua_sheet, ORIGIN_UA); 00091 } 00092 00093 return result; 00094 } 00095 00096 /** 00097 * cr_cascade_get_sheet: 00098 *@a_this: the current instance of #CRCascade. 00099 *@a_origin: the origin of the style sheet as 00100 *defined in the css2 spec in chapter 6.4. 00101 *Gets a given origin sheet. 00102 * 00103 *Gets a sheet, part of the cascade. 00104 *Note that the returned stylesheet 00105 *is refcounted so if the caller wants 00106 *to manage it's lifecycle, it must use 00107 *cr_stylesheet_ref()/cr_stylesheet_unref() instead 00108 *of the cr_stylesheet_destroy() method. 00109 *Returns the style sheet, or NULL if it does not 00110 *exist. 00111 */ 00112 CRStyleSheet * 00113 cr_cascade_get_sheet (CRCascade * a_this, enum CRStyleOrigin a_origin) 00114 { 00115 g_return_val_if_fail (a_this 00116 && a_origin >= ORIGIN_UA 00117 && a_origin < NB_ORIGINS, NULL); 00118 00119 return PRIVATE (a_this)->sheets[a_origin]; 00120 } 00121 00122 /** 00123 * cr_cascade_set_sheet: 00124 *@a_this: the current instance of #CRCascade. 00125 *@a_sheet: the stylesheet to set. 00126 *@a_origin: the origin of the stylesheet. 00127 * 00128 *Sets a stylesheet in the cascade 00129 * 00130 *Returns CR_OK upon successfull completion, an error 00131 *code otherwise. 00132 */ 00133 enum CRStatus 00134 cr_cascade_set_sheet (CRCascade * a_this, 00135 CRStyleSheet * a_sheet, enum CRStyleOrigin a_origin) 00136 { 00137 g_return_val_if_fail (a_this 00138 && a_sheet 00139 && a_origin >= ORIGIN_UA 00140 && a_origin < NB_ORIGINS, CR_BAD_PARAM_ERROR); 00141 00142 if (PRIVATE (a_this)->sheets[a_origin]) 00143 cr_stylesheet_unref (PRIVATE (a_this)->sheets[a_origin]); 00144 PRIVATE (a_this)->sheets[a_origin] = a_sheet; 00145 cr_stylesheet_ref (a_sheet); 00146 a_sheet->origin = a_origin; 00147 return CR_OK; 00148 } 00149 00150 /** 00151 *cr_cascade_ref: 00152 *@a_this: the current instance of #CRCascade 00153 * 00154 *Increases the reference counter of the current instance 00155 *of #CRCascade. 00156 */ 00157 void 00158 cr_cascade_ref (CRCascade * a_this) 00159 { 00160 g_return_if_fail (a_this && PRIVATE (a_this)); 00161 00162 PRIVATE (a_this)->ref_count++; 00163 } 00164 00165 /** 00166 * cr_cascade_unref: 00167 *@a_this: the current instance of 00168 *#CRCascade. 00169 * 00170 *Decrements the reference counter associated 00171 *to this instance of #CRCascade. If the reference 00172 *counter reaches zero, the instance is destroyed 00173 *using cr_cascade_destroy() 00174 */ 00175 void 00176 cr_cascade_unref (CRCascade * a_this) 00177 { 00178 g_return_if_fail (a_this && PRIVATE (a_this)); 00179 00180 if (PRIVATE (a_this)->ref_count) 00181 PRIVATE (a_this)->ref_count--; 00182 if (!PRIVATE (a_this)->ref_count) { 00183 cr_cascade_destroy (a_this); 00184 } 00185 } 00186 00187 /** 00188 * cr_cascade_destroy: 00189 * @a_this: the current instance of #CRCascade 00190 * 00191 * Destructor of #CRCascade. 00192 */ 00193 void 00194 cr_cascade_destroy (CRCascade * a_this) 00195 { 00196 g_return_if_fail (a_this); 00197 00198 if (PRIVATE (a_this)) { 00199 gulong i = 0; 00200 00201 for (i = 0; PRIVATE (a_this)->sheets && i < NB_ORIGINS; i++) { 00202 if (PRIVATE (a_this)->sheets[i]) { 00203 if (cr_stylesheet_unref 00204 (PRIVATE (a_this)->sheets[i]) 00205 == TRUE) { 00206 PRIVATE (a_this)->sheets[i] = NULL; 00207 } 00208 } 00209 } 00210 g_free (PRIVATE (a_this)); 00211 PRIVATE (a_this) = NULL; 00212 } 00213 g_free (a_this); 00214 }