summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@seketeli.org>2003-06-18 19:28:42 +0000
committerDodji Seketeli <dodji@src.gnome.org>2003-06-18 19:28:42 +0000
commit127628a4ae11a60cbf609ae1396345190f9d1129 (patch)
treefb108984e6df5814bac75621a7edec0a6bf65577
parent28260b0a57917142eaeedd918d7185a80d66ea6b (diff)
downloadlibcroco-127628a4ae11a60cbf609ae1396345190f9d1129.tar.gz
added cr_statement_font_face_rule_parse_from_buf () . and a generic
2003-06-18 Dodji Seketeli <dodji@seketeli.org> * src/parser/cr-statement.[ch]: added cr_statement_font_face_rule_parse_from_buf () . and a generic cr_statement_parse_from_buf () that knows how to a parse virtually any css2 statement. This needs debugging though. * src/parser/cr-parser.c: fixed some possible sigsev that could occur when trying to access a null sac handler. Dodji.
-rw-r--r--ChangeLog9
-rw-r--r--TODO7
-rw-r--r--src/parser/cr-parser.c13
-rw-r--r--src/parser/cr-statement.c222
-rw-r--r--src/parser/cr-statement.h16
-rw-r--r--tests/test4-main.c34
6 files changed, 286 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 43800ca..d536551 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2003-06-18 Dodji Seketeli <dodji@seketeli.org>
+ * src/parser/cr-statement.[ch]:
+ added cr_statement_font_face_rule_parse_from_buf () .
+ and a generic cr_statement_parse_from_buf () that knows
+ how to a parse virtually any css2 statement. This needs debugging
+ though.
+
+ * src/parser/cr-parser.c: fixed some possible sigsev
+ that could occur when trying to access a null sac handler.
+
* tests/test4-main.c: updated the test routine to test
cr_statement_at_charset_rule_parse_from_buf().
diff --git a/TODO b/TODO
index c4ffb30..7214f34 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,12 @@
*coding:)
-Provide support for font selection. (hard, started well underway.)
+Code a cr_statement_at_import_rule_parse () function and
+include it support in cr_statement_parse_from_buf ().
+
+Code a test case for cr_statement_parse_from_buf ().
+
+Provide support for font selection. (hard, started, is well underway.)
First make sure to be able to gather all the font related property
values.
Then, figure out how to implement a font selector that uses pango.
diff --git a/src/parser/cr-parser.c b/src/parser/cr-parser.c
index 402fcd0..58454c7 100644
--- a/src/parser/cr-parser.c
+++ b/src/parser/cr-parser.c
@@ -3048,7 +3048,8 @@ cr_parser_parse_stylesheet (CRParser *a_this)
PRIVATE (a_this)->state = READY_STATE ;
- if (PRIVATE (a_this)->sac_handler->start_document)
+ if (PRIVATE (a_this)->sac_handler
+ && PRIVATE (a_this)->sac_handler->start_document)
{
PRIVATE (a_this)->sac_handler->start_document
(PRIVATE (a_this)->sac_handler) ;
@@ -3161,8 +3162,8 @@ cr_parser_parse_stylesheet (CRParser *a_this)
if (status == CR_OK)
{
if (import_string
- && PRIVATE
- (a_this)->sac_handler->
+ && PRIVATE (a_this)->sac_handler
+ && PRIVATE(a_this)->sac_handler->
import_style)
{
PRIVATE (a_this)->sac_handler->
@@ -4924,7 +4925,8 @@ cr_parser_parse_font_face (CRParser *a_this)
*here, call the relevant SAC handler.
*/
- if (PRIVATE (a_this)->sac_handler->start_font_face)
+ if (PRIVATE (a_this)->sac_handler
+ && PRIVATE (a_this)->sac_handler->start_font_face)
{
PRIVATE (a_this)->sac_handler->start_font_face
(PRIVATE (a_this)->sac_handler) ;
@@ -4948,7 +4950,8 @@ cr_parser_parse_font_face (CRParser *a_this)
*/
cr_term_ref (css_expression) ;
- if (PRIVATE (a_this)->sac_handler->property)
+ if (PRIVATE (a_this)->sac_handler &&
+ PRIVATE (a_this)->sac_handler->property)
{
PRIVATE (a_this)->sac_handler->property
(PRIVATE (a_this)->sac_handler,
diff --git a/src/parser/cr-statement.c b/src/parser/cr-statement.c
index 11ee840..ce1ea56 100644
--- a/src/parser/cr-statement.c
+++ b/src/parser/cr-statement.c
@@ -1,4 +1,4 @@
-/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/*
* This file is part of The Croco Library
@@ -56,6 +56,82 @@ static void
cr_statement_dump_import_rule (CRStatement *a_this, FILE *a_fp,
gulong a_indent) ;
+static void
+parse_font_face_start_font_face_cb (CRDocHandler *a_this)
+{
+ CRStatement *stmt = NULL ;
+ enum CRStatus status = CR_OK ;
+
+ stmt = cr_statement_new_at_font_face_rule (NULL,
+ NULL) ;
+ g_return_if_fail (stmt) ;
+
+ status = cr_doc_handler_set_ctxt (a_this, stmt) ;
+ g_return_if_fail (status == CR_OK) ;
+}
+
+static void
+parse_font_face_property_cb (CRDocHandler *a_this,
+ GString *a_name,
+ CRTerm *a_value)
+{
+ enum CRStatus status = CR_OK ;
+ GString *name = NULL ;
+ CRDeclaration *decl = NULL ;
+ CRStatement *stmt = NULL ;
+
+ g_return_if_fail (a_this && a_name) ;
+
+ status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&stmt) ;
+ g_return_if_fail (status == CR_OK && stmt) ;
+ g_return_if_fail (stmt->type == AT_FONT_FACE_RULE_STMT) ;
+
+ name = g_string_new_len (a_name->str, a_name->len) ;
+ g_return_if_fail (name) ;
+ decl = cr_declaration_new (stmt, name, a_value) ;
+ if (!decl)
+ {
+ cr_utils_trace_info ("cr_declaration_new () failed.") ;
+ goto error ;
+ }
+ name = NULL ;
+
+ stmt->kind.font_face_rule->decls_list =
+ cr_declaration_append (stmt->kind.font_face_rule->decls_list,
+ decl) ;
+ if (!stmt->kind.font_face_rule->decls_list)
+ goto error ;
+ decl = NULL ;
+
+ error:
+ if (decl)
+ {
+ cr_declaration_unref (decl) ;
+ decl = NULL ;
+ }
+ if (name)
+ {
+ g_string_free (name, TRUE) ;
+ name = NULL ;
+ }
+}
+
+static void
+parse_font_face_end_font_face_cb (CRDocHandler *a_this)
+
+{
+ CRStatement *result = NULL ;
+ enum CRStatus status = CR_OK ;
+
+ g_return_if_fail (a_this) ;
+
+ status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&result) ;
+ g_return_if_fail (status == CR_OK && result) ;
+ g_return_if_fail (result->type == AT_FONT_FACE_RULE_STMT) ;
+
+ status = cr_doc_handler_set_result (a_this, result) ;
+ g_return_if_fail (status == CR_OK) ;
+}
static void
parse_page_start_page_cb (CRDocHandler *a_this,
@@ -691,6 +767,78 @@ cr_statement_dump_import_rule (CRStatement *a_this, FILE *a_fp,
*public functions
******************/
+/**
+ *Parses a buffer that contains a css statement and returns
+ *an instance of #CRStatement in case of successfull parsing.
+ *TODO: at support of "@import" rules.
+ *@param a_buf the buffer to parse.
+ *@param a_encoding the character encoding of a_buf.
+ *@return the newly built instance of #CRStatement in case
+ *of successfull parsing, NULL otherwise.
+ */
+CRStatement *
+cr_statement_parse_from_buf (const guchar *a_buf,
+ enum CREncoding a_encoding)
+{
+ CRStatement *result = NULL ;
+
+ /*
+ *The strategy of this function is "brute force".
+ *It tries to parse all the types of #CRStatement it knows about.
+ *I could do this a smarter way but I don't have the time now.
+ *I think I will revisit this when time of performances and
+ *pull based incremental parsing comes.
+ */
+
+ result = cr_statement_ruleset_parse_from_buf (a_buf, a_encoding) ;
+ if (!result)
+ {
+ result = cr_statement_at_charset_rule_parse_from_buf
+ (a_buf, a_encoding) ;
+ if (result)
+ goto out ;
+ }
+ if (!result)
+ {
+ result = cr_statement_at_media_rule_parse_from_buf
+ (a_buf, a_encoding) ;
+ if (result)
+ goto out ;
+ }
+ if (!result)
+ {
+ result = cr_statement_at_charset_rule_parse_from_buf
+ (a_buf, a_encoding) ;
+ if (result)
+ goto out ;
+ }
+ if (!result)
+ {
+ result = cr_statement_font_face_rule_parse_from_buf
+ (a_buf, a_encoding) ;
+ if (result)
+ goto out ;
+ }
+ if (!result)
+ {
+ result = cr_statement_at_page_rule_parse_from_buf
+ (a_buf, a_encoding) ;
+ if (result)
+ goto out ;
+ }
+
+ out:
+ return result ;
+}
+
+/**
+ *Parses a buffer that contains a ruleset statement an instanciates
+ *a #CRStatement of type RULESET_STMT.
+ *@param a_buf the buffer to parse.
+ *@param a_enc the character encoding of a_buf.
+ *@param the newly built instance of #CRStatement in case of successfull parsing,
+ *NULL otherwise.
+ */
CRStatement *
cr_statement_ruleset_parse_from_buf (const guchar * a_buf,
enum CREncoding a_enc)
@@ -1239,8 +1387,6 @@ cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet,
{
CRStatement *result = NULL ;
- g_return_val_if_fail (a_sheet, NULL) ;
-
result = g_try_malloc (sizeof (CRStatement)) ;
if (!result)
@@ -1264,8 +1410,76 @@ cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet,
sizeof (CRAtFontFaceRule));
result->kind.font_face_rule->decls_list = a_font_decls ;
- cr_statement_set_parent_sheet (result, a_sheet) ;
+ if (a_sheet)
+ cr_statement_set_parent_sheet (result, a_sheet) ;
+
+ return result ;
+}
+
+/**
+ *Parses a buffer that contains an "@font-face" rule and builds
+ *an instance of #CRStatement of type AT_FONT_FACE_RULE_STMT out of it.
+ *@param a_buf the buffer to parse.
+ *@param a_encoding the character encoding of a_buf.
+ *@return the newly built instance of #CRStatement in case of successufull
+ *parsing, NULL otherwise.
+ */
+CRStatement *
+cr_statement_font_face_rule_parse_from_buf (const guchar *a_buf,
+ enum CREncoding a_encoding)
+{
+ CRStatement *result = NULL ;
+ CRParser *parser = NULL ;
+ CRDocHandler *sac_handler = NULL ;
+ enum CRStatus status = CR_OK ;
+
+ parser = cr_parser_new_from_buf (a_buf, strlen (a_buf),
+ a_encoding, FALSE) ;
+ if (!parser)
+ goto cleanup ;
+
+ sac_handler = cr_doc_handler_new () ;
+ if (!sac_handler)
+ goto cleanup ;
+
+ /*
+ *set sac callbacks here
+ */
+ sac_handler->start_font_face = parse_font_face_start_font_face_cb ;
+ sac_handler->property = parse_font_face_property_cb ;
+ sac_handler->end_font_face = parse_font_face_end_font_face_cb ;
+ status = cr_parser_set_sac_handler (parser, sac_handler) ;
+ if (status != CR_OK)
+ goto cleanup ;
+
+ /*
+ *cleanup spaces of comment that may be there before the real
+ *"@font-face" thing.
+ */
+ status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
+ if (status != CR_OK)
+ goto cleanup ;
+
+ status = cr_parser_parse_font_face (parser) ;
+ if (status != CR_OK)
+ goto cleanup ;
+
+ status = cr_doc_handler_get_result (sac_handler, (gpointer*)&result) ;
+ if (status != CR_OK || !result)
+ goto cleanup ;
+
+ cleanup:
+ if (parser)
+ {
+ cr_parser_destroy (parser) ;
+ parser = NULL ;
+ }
+ if (sac_handler)
+ {
+ cr_doc_handler_unref (sac_handler) ;
+ sac_handler = NULL ;
+ }
return result ;
}
diff --git a/src/parser/cr-statement.h b/src/parser/cr-statement.h
index d1d7686..e293235 100644
--- a/src/parser/cr-statement.h
+++ b/src/parser/cr-statement.h
@@ -169,7 +169,7 @@ enum CRStatementType
AT_CHARSET_RULE_STMT,
/**A css2 font face rule*/
- AT_FONT_FACE_RULE_STMT
+ AT_FONT_FACE_RULE_STMT
} ;
@@ -232,6 +232,10 @@ struct _CRStatement
} ;
+CRStatement *
+cr_statement_parse_from_buf (const guchar *a_buf,
+ enum CREncoding a_encoding) ;
+
CRStatement*
cr_statement_new_ruleset (CRStyleSheet *a_sheet,
CRSelector *a_sel_list,
@@ -251,6 +255,9 @@ CRStatement *
cr_statement_new_at_media_rule (CRStyleSheet *a_sheet,
CRStatement *a_ruleset,
GList *a_media) ;
+CRStatement *
+cr_statement_at_media_rule_parse_from_buf (const guchar *a_buf,
+ enum CREncoding a_enc) ;
CRStatement *
cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet,
@@ -258,13 +265,14 @@ cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet,
CRStatement *
cr_statement_at_charset_rule_parse_from_buf (const guchar *a_buf,
enum CREncoding a_encoding);
-CRStatement *
-cr_statement_at_media_rule_parse_from_buf (const guchar *a_buf,
- enum CREncoding a_enc) ;
+
CRStatement *
cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet,
CRDeclaration *a_font_decls) ;
+CRStatement *
+cr_statement_font_face_rule_parse_from_buf (const guchar *a_buf,
+ enum CREncoding a_encoding) ;
CRStatement *
cr_statement_new_at_page_rule (CRStyleSheet *a_sheet,
diff --git a/tests/test4-main.c b/tests/test4-main.c
index 1006c23..414455a 100644
--- a/tests/test4-main.c
+++ b/tests/test4-main.c
@@ -56,6 +56,13 @@ const guchar *gv_at_charset_buf =
"@charset \"ISO-8859-1\" ; "
;
+const guchar *gv_at_font_face_buf=
+"@font-face {"
+" font-family: \"Robson Celtic\";"
+" src: url(\"http://site/fonts/rob-celt\")"
+"}"
+;
+
static void
display_help (char *prg_name) ;
@@ -232,6 +239,24 @@ test_cr_statement_at_charset_rule_parse (void)
return CR_OK ;
}
+
+static enum CRStatus
+test_cr_statement_font_face_rule_parse_from_buf (void)
+{
+ CRStatement *stmt = NULL ;
+
+ stmt = cr_statement_font_face_rule_parse_from_buf (gv_at_font_face_buf,
+ CR_UTF_8) ;
+ g_return_val_if_fail (stmt, CR_ERROR) ;
+ if (stmt)
+ {
+ cr_statement_destroy (stmt) ;
+ stmt = NULL ;
+ }
+
+ return CR_OK ;
+}
+
/**
*The entry point of the testing routine.
*/
@@ -269,7 +294,14 @@ main (int argc, char ** argv)
return 0 ;
}
- test_cr_statement_at_charset_rule_parse () ;
+ status = test_cr_statement_at_charset_rule_parse () ;
+ if (status != CR_OK)
+ {
+ g_print ("\nKO\n") ;
+ return 0 ;
+ }
+
+ status = test_cr_statement_font_face_rule_parse_from_buf () ;
if (status != CR_OK)
{
g_print ("\nKO\n") ;