1/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ 2 3/* 4 * This file is part of The Croco Library 5 * 6 * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of version 2.1 of the 10 * GNU Lesser General Public 11 * License as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the 19 * GNU Lesser General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 22 * USA 23 */ 24 25/* 26 *$Id: cr-cascade.c,v 1.7 2005/05/10 19:48:56 dodji Exp $ 27 */ 28 29#include <config.h> 30#include <string.h> 31#include "cr-cascade.h" 32 33#define PRIVATE(a_this) ((a_this)->priv) 34 35struct _CRCascadePriv { 36 /** 37 *the 3 style sheets of the cascade: 38 *author, user, and useragent sheet. 39 *Intended to be addressed by 40 *sheets[ORIGIN_AUTHOR] or sheets[ORIGIN_USER] 41 *of sheets[ORIGIN_UA] ; 42 */ 43 CRStyleSheet *sheets[3]; 44 guint ref_count; 45}; 46 47/** 48 * cr_cascade_new: 49 *@a_author_sheet: the author origin style sheet. May be NULL. 50 *@a_user_sheet: the user origin style sheet. May be NULL. 51 *@a_ua_sheet: the user agent origin style sheet. May be NULL. 52 * 53 *Constructor of the #CRCascade class. 54 *Note that all three parameters of this 55 *method are ref counted and their refcount is increased. 56 *Their refcount will be decreased at the destruction of 57 *the instance of #CRCascade. 58 *So the caller should not call their destructor. The caller 59 *should call their ref/unref method instead if it wants 60 * 61 *Returns the newly built instance of CRCascade or NULL if 62 *an error arose during constrution. 63 */ 64CRCascade * 65cr_cascade_new (CRStyleSheet * a_author_sheet, 66 CRStyleSheet * a_user_sheet, CRStyleSheet * a_ua_sheet) 67{ 68 CRCascade *result = NULL; 69 70 result = g_try_malloc (sizeof (CRCascade)); 71 if (!result) { 72 cr_utils_trace_info ("Out of memory"); 73 return NULL; 74 } 75 memset (result, 0, sizeof (CRCascade)); 76 77 PRIVATE (result) = g_try_malloc (sizeof (CRCascadePriv)); 78 if (!PRIVATE (result)) { 79 cr_utils_trace_info ("Out of memory"); 80 return NULL; 81 } 82 memset (PRIVATE (result), 0, sizeof (CRCascadePriv)); 83 84 if (a_author_sheet) { 85 cr_cascade_set_sheet (result, a_author_sheet, ORIGIN_AUTHOR); 86 } 87 if (a_user_sheet) { 88 cr_cascade_set_sheet (result, a_user_sheet, ORIGIN_USER); 89 } 90 if (a_ua_sheet) { 91 cr_cascade_set_sheet (result, a_ua_sheet, ORIGIN_UA); 92 } 93 94 return result; 95} 96 97/** 98 * cr_cascade_get_sheet: 99 *@a_this: the current instance of #CRCascade. 100 *@a_origin: the origin of the style sheet as 101 *defined in the css2 spec in chapter 6.4. 102 *Gets a given origin sheet. 103 * 104 *Gets a sheet, part of the cascade. 105 *Note that the returned stylesheet 106 *is refcounted so if the caller wants 107 *to manage it's lifecycle, it must use 108 *cr_stylesheet_ref()/cr_stylesheet_unref() instead 109 *of the cr_stylesheet_destroy() method. 110 *Returns the style sheet, or NULL if it does not 111 *exist. 112 */ 113CRStyleSheet * 114cr_cascade_get_sheet (CRCascade * a_this, enum CRStyleOrigin a_origin) 115{ 116 g_return_val_if_fail (a_this 117 && a_origin >= ORIGIN_UA 118 && a_origin < NB_ORIGINS, NULL); 119 120 return PRIVATE (a_this)->sheets[a_origin]; 121} 122 123/** 124 * cr_cascade_set_sheet: 125 *@a_this: the current instance of #CRCascade. 126 *@a_sheet: the stylesheet to set. 127 *@a_origin: the origin of the stylesheet. 128 * 129 *Sets a stylesheet in the cascade 130 * 131 *Returns CR_OK upon successfull completion, an error 132 *code otherwise. 133 */ 134enum CRStatus 135cr_cascade_set_sheet (CRCascade * a_this, 136 CRStyleSheet * a_sheet, enum CRStyleOrigin a_origin) 137{ 138 g_return_val_if_fail (a_this 139 && a_sheet 140 && a_origin >= ORIGIN_UA 141 && a_origin < NB_ORIGINS, CR_BAD_PARAM_ERROR); 142 143 if (PRIVATE (a_this)->sheets[a_origin]) 144 cr_stylesheet_unref (PRIVATE (a_this)->sheets[a_origin]); 145 PRIVATE (a_this)->sheets[a_origin] = a_sheet; 146 cr_stylesheet_ref (a_sheet); 147 a_sheet->origin = a_origin; 148 return CR_OK; 149} 150 151/** 152 *cr_cascade_ref: 153 *@a_this: the current instance of #CRCascade 154 * 155 *Increases the reference counter of the current instance 156 *of #CRCascade. 157 */ 158void 159cr_cascade_ref (CRCascade * a_this) 160{ 161 g_return_if_fail (a_this && PRIVATE (a_this)); 162 163 PRIVATE (a_this)->ref_count++; 164} 165 166/** 167 * cr_cascade_unref: 168 *@a_this: the current instance of 169 *#CRCascade. 170 * 171 *Decrements the reference counter associated 172 *to this instance of #CRCascade. If the reference 173 *counter reaches zero, the instance is destroyed 174 *using cr_cascade_destroy() 175 */ 176void 177cr_cascade_unref (CRCascade * a_this) 178{ 179 g_return_if_fail (a_this && PRIVATE (a_this)); 180 181 if (PRIVATE (a_this)->ref_count) 182 PRIVATE (a_this)->ref_count--; 183 if (!PRIVATE (a_this)->ref_count) { 184 cr_cascade_destroy (a_this); 185 } 186} 187 188/** 189 * cr_cascade_destroy: 190 * @a_this: the current instance of #CRCascade 191 * 192 * Destructor of #CRCascade. 193 */ 194void 195cr_cascade_destroy (CRCascade * a_this) 196{ 197 g_return_if_fail (a_this); 198 199 if (PRIVATE (a_this)) { 200 gulong i = 0; 201 202 for (i = 0; PRIVATE (a_this)->sheets && i < NB_ORIGINS; i++) { 203 if (PRIVATE (a_this)->sheets[i]) { 204 if (cr_stylesheet_unref 205 (PRIVATE (a_this)->sheets[i]) 206 == TRUE) { 207 PRIVATE (a_this)->sheets[i] = NULL; 208 } 209 } 210 } 211 g_free (PRIVATE (a_this)); 212 PRIVATE (a_this) = NULL; 213 } 214 g_free (a_this); 215} 216