Compare commits
128 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 519b6c542c | |||
| c6471ee874 | |||
| 261b8c7ee6 | |||
| f58f0732c2 | |||
| c5a4a26f06 | |||
| faff08193a | |||
| 3046358d38 | |||
| e81f033ece | |||
| 5c608fe070 | |||
| a2db956492 | |||
| 8d51038cb1 | |||
| 86c86e0860 | |||
| 324f5472a2 | |||
| c20360dd98 | |||
| 1b6252ebf0 | |||
| b4c8ba4de7 | |||
| ad34f731e9 | |||
| 198207f1ff | |||
| 6120f11ed3 | |||
| 0a440a804f | |||
| 117fc68195 | |||
| f310609a66 | |||
| 8001c7d972 | |||
| 023b695422 | |||
| ec6ce0707a | |||
| f37573f8dc | |||
| 49f8b571b9 | |||
| e1cd996617 | |||
| 24cc721bc6 | |||
| d41580adfc | |||
| 3ab65b7da2 | |||
| 79238b0d8f | |||
| 2e0a56665a | |||
| 76826cfa2f | |||
| 37671d2bd0 | |||
| 04d24b7cd2 | |||
| 085d34cbb0 | |||
| 46143492a2 | |||
| a475d72d47 | |||
| a8f712b09a | |||
| 2fb202187c | |||
| 207c0b32b4 | |||
| 35f60dc918 | |||
| 1cd9396154 | |||
| de73ac980f | |||
| acaec5f186 | |||
| c8589a9a2f | |||
| a31e5f7a8c | |||
| e0a01ba174 | |||
| 98e076b51e | |||
| f3db19d694 | |||
| 607502ef43 | |||
| acddc317da | |||
| 7f99c1e588 | |||
| 5f3e5a0406 | |||
| 23080d47b5 | |||
| f0d2f99239 | |||
| e7b9ecc99a | |||
| dce8c11b07 | |||
| 7ccec19501 | |||
| 93b643c44d | |||
| 21616f6e2e | |||
| 8157004068 | |||
| 8d69bda27a | |||
| dbdb81f411 | |||
| 28fbcf6abe | |||
| 1fd339c46f | |||
| b830bdca37 | |||
| 45bc4ed321 | |||
| 3988847a05 | |||
| 9c862d7736 | |||
| d99ae4b6c2 | |||
| 96f9cbcabf | |||
| 3597f7e8b1 | |||
| 38227dc972 | |||
| aa50e92c65 | |||
| 753ad64cbc | |||
| 3fb44ae651 | |||
| 76fb80f46c | |||
| 684b6459f1 | |||
| 904a9d0c98 | |||
| 32e256e5ab | |||
| d4d46e8125 | |||
| 661720ef8b | |||
| 013591d68d | |||
| a938c14d11 | |||
| d6cc10ea74 | |||
| f25832455f | |||
| 42ea95c54e | |||
| 46e7b44ffa | |||
| a27737b04e | |||
| bd2d07e671 | |||
| fde21b57cd | |||
| 637bd13f3f | |||
| eadd90c22e | |||
| 279cb5717c | |||
| b91fbfd5a0 | |||
| 88086ea91a | |||
| 0842d084dd | |||
| 838b25177f | |||
| b39d0cec3c | |||
| f0c72bdc3b | |||
| 427d216081 | |||
| dc8b5f75a4 | |||
| b6f2969872 | |||
| 6eed78e3de | |||
| c4aa060118 | |||
| 0bf4c2420d | |||
| aac2556762 | |||
| f813bc1823 | |||
| e6631a7b66 | |||
| fbe0e32813 | |||
| 2594593de2 | |||
| ef982b7d46 | |||
| 0432b850c5 | |||
| 1b362d1f01 | |||
| 7ce968f297 | |||
| 0e15b4a367 | |||
| de0942b0b8 | |||
| b804235aea | |||
| 6bc32a3d5d | |||
| 5e24454764 | |||
| d9cf0ff684 | |||
| 5b78a3048f | |||
| 676ac380cd | |||
| dce2c58799 | |||
| f3d1666394 | |||
| 8af0782261 |
+3
-2
@@ -13,7 +13,7 @@ stages:
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v3
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v4
|
||||
stage: build
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
@@ -26,6 +26,7 @@ fedora-x86_64:
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
- "${CI_PROJECT_DIR}/_build/report.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*.png"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
<<: *cache-paths
|
||||
@@ -99,7 +100,7 @@ flatpak-master:icon-browser:
|
||||
<<: *flatpak-master
|
||||
|
||||
pages:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v3
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v4
|
||||
stage: deploy
|
||||
script:
|
||||
- meson -Ddocumentation=true _build .
|
||||
|
||||
@@ -11,6 +11,7 @@ RUN dnf -y install \
|
||||
ccache \
|
||||
colord-devel \
|
||||
cups-devel \
|
||||
dejavu-sans-mono-fonts \
|
||||
desktop-file-utils \
|
||||
elfutils-libelf-devel \
|
||||
fribidi-devel \
|
||||
|
||||
@@ -19,11 +19,11 @@ aparser.add_argument('--branch', metavar='NAME',
|
||||
default='master')
|
||||
aparser.add_argument('--output', metavar='FILE',
|
||||
help='The output file, stdout by default',
|
||||
type=argparse.FileType('w'),
|
||||
type=argparse.FileType('w', encoding='UTF-8'),
|
||||
default=sys.stdout)
|
||||
aparser.add_argument('infile', metavar='FILE',
|
||||
help='The input testlog.json, stdin by default',
|
||||
type=argparse.FileType('r'),
|
||||
type=argparse.FileType('r', encoding='UTF-8'),
|
||||
default=sys.stdin)
|
||||
|
||||
args = aparser.parse_args()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v3"
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v4"
|
||||
|
||||
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
|
||||
--file "Dockerfile" .
|
||||
|
||||
@@ -32,7 +32,6 @@ xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
--print-errorlogs \
|
||||
--suite=gtk \
|
||||
--no-suite=gtk:gsk \
|
||||
--no-suite=gtk:reftest \
|
||||
--no-suite=gtk:a11y
|
||||
|
||||
# Save the exit code
|
||||
|
||||
@@ -13,19 +13,22 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
||||
@@ -13,19 +13,23 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
||||
@@ -12,19 +12,23 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
||||
@@ -11,19 +11,22 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
||||
@@ -243,7 +243,7 @@ pressed_cb (GtkGesture *gesture,
|
||||
GtkWidget *child;
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
child = gtk_widget_pick (widget, x, y);
|
||||
child = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
|
||||
|
||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
@@ -320,7 +320,7 @@ released_cb (GtkGesture *gesture,
|
||||
GtkWidget *child;
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
child = gtk_widget_pick (widget, x, y);
|
||||
child = gtk_widget_pick (widget, x, y, 0);
|
||||
|
||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@ do_overlay (GtkWidget *do_widget)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), vbox);
|
||||
gtk_widget_set_can_pick (vbox, FALSE);
|
||||
gtk_widget_set_can_target (vbox, FALSE);
|
||||
gtk_widget_set_halign (vbox, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (vbox, GTK_ALIGN_CENTER);
|
||||
|
||||
|
||||
@@ -66,13 +66,13 @@ do_overlay2 (GtkWidget *do_widget)
|
||||
|
||||
image = gtk_picture_new_for_resource ("/overlay2/decor1.png");
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
|
||||
gtk_widget_set_can_pick (image, FALSE);
|
||||
gtk_widget_set_can_target (image, FALSE);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_START);
|
||||
|
||||
image = gtk_picture_new_for_resource ("/overlay2/decor2.png");
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
|
||||
gtk_widget_set_can_pick (image, FALSE);
|
||||
gtk_widget_set_can_target (image, FALSE);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_END);
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ puzzle_button_pressed (GtkGestureMultiPress *gesture,
|
||||
int l, t, i;
|
||||
int pos;
|
||||
|
||||
child = gtk_widget_pick (grid, x, y);
|
||||
child = gtk_widget_pick (grid, x, y, GTK_PICK_DEFAULT);
|
||||
|
||||
if (!child)
|
||||
{
|
||||
|
||||
@@ -152,6 +152,8 @@ gsk_transform_get_category
|
||||
<SUBSECTION>
|
||||
gsk_transform_print
|
||||
gsk_transform_to_string
|
||||
gsk_transform_parse
|
||||
<SUBSECTION>
|
||||
gsk_transform_to_matrix
|
||||
gsk_transform_to_2d
|
||||
gsk_transform_to_affine
|
||||
|
||||
@@ -4507,6 +4507,7 @@ gtk_widget_compute_bounds
|
||||
gtk_widget_compute_transform
|
||||
gtk_widget_compute_point
|
||||
gtk_widget_contains
|
||||
GtkPickFlags
|
||||
gtk_widget_pick
|
||||
gtk_widget_get_can_default
|
||||
gtk_widget_set_can_default
|
||||
@@ -4515,8 +4516,8 @@ gtk_widget_set_can_focus
|
||||
gtk_widget_get_focus_on_click
|
||||
gtk_widget_set_focus_on_click
|
||||
gtk_widget_set_focus_child
|
||||
gtk_widget_get_can_pick
|
||||
gtk_widget_set_can_pick
|
||||
gtk_widget_get_can_target
|
||||
gtk_widget_set_can_target
|
||||
gtk_widget_get_has_surface
|
||||
gtk_widget_set_has_surface
|
||||
gtk_widget_get_sensitive
|
||||
@@ -5085,20 +5086,21 @@ gtk_css_provider_load_from_path
|
||||
gtk_css_provider_load_from_resource
|
||||
gtk_css_provider_new
|
||||
gtk_css_provider_to_string
|
||||
GTK_CSS_PROVIDER_ERROR
|
||||
GtkCssProviderError
|
||||
GTK_CSS_PARSER_ERROR
|
||||
GtkCssParserError
|
||||
GtkCssParserWarning
|
||||
<SUBSECTION>
|
||||
GtkCssLocation
|
||||
GtkCssSection
|
||||
GtkCssSectionType
|
||||
gtk_css_section_get_end_line
|
||||
gtk_css_section_get_end_position
|
||||
gtk_css_section_get_file
|
||||
gtk_css_section_get_parent
|
||||
gtk_css_section_get_section_type
|
||||
gtk_css_section_get_start_line
|
||||
gtk_css_section_get_start_position
|
||||
gtk_css_section_new
|
||||
gtk_css_section_ref
|
||||
gtk_css_section_unref
|
||||
gtk_css_section_print
|
||||
gtk_css_section_to_string
|
||||
gtk_css_section_get_file
|
||||
gtk_css_section_get_parent
|
||||
gtk_css_section_get_start_location
|
||||
gtk_css_section_get_end_location
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_CSS_PROVIDER
|
||||
GTK_CSS_PROVIDER
|
||||
|
||||
+4
-17
@@ -38,9 +38,6 @@
|
||||
|
||||
struct _GdkFrameClockIdlePrivate
|
||||
{
|
||||
GTimer *timer;
|
||||
/* timer_base is used to avoid ever going backward */
|
||||
gint64 timer_base;
|
||||
gint64 frame_time;
|
||||
gint64 min_next_frame_time;
|
||||
gint64 sleep_serial;
|
||||
@@ -161,22 +158,12 @@ compute_frame_time (GdkFrameClockIdle *idle)
|
||||
{
|
||||
GdkFrameClockIdlePrivate *priv = idle->priv;
|
||||
gint64 computed_frame_time;
|
||||
gint64 elapsed;
|
||||
|
||||
elapsed = g_get_monotonic_time () + priv->timer_base;
|
||||
if (elapsed < priv->frame_time)
|
||||
{
|
||||
/* clock went backward. adapt to that by forevermore increasing
|
||||
* timer_base. For now, assume we've gone forward in time 1ms.
|
||||
*/
|
||||
/* hmm. just fix GTimer? */
|
||||
computed_frame_time = g_get_monotonic_time ();
|
||||
|
||||
/* ensure monotonicity of frame time */
|
||||
if (computed_frame_time <= priv->frame_time)
|
||||
computed_frame_time = priv->frame_time + 1;
|
||||
priv->timer_base += (priv->frame_time - elapsed) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
computed_frame_time = elapsed;
|
||||
}
|
||||
|
||||
return computed_frame_time;
|
||||
}
|
||||
|
||||
+183
-1
@@ -23,7 +23,9 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gdkrgba.h"
|
||||
|
||||
#include "gdkrgbaprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
@@ -393,3 +395,183 @@ gdk_rgba_to_string (const GdkRGBA *rgba)
|
||||
alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color_channel_value (GtkCssParser *parser,
|
||||
double *value,
|
||||
gboolean is_percentage)
|
||||
{
|
||||
if (is_percentage)
|
||||
{
|
||||
if (!gtk_css_parser_consume_percentage (parser, value))
|
||||
return FALSE;
|
||||
|
||||
*value = CLAMP (*value, 0.0, 100.0) / 100.0;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gtk_css_parser_consume_number (parser, value))
|
||||
return FALSE;
|
||||
|
||||
*value = CLAMP (*value, 0.0, 255.0) / 255.0;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_color_channel (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GdkRGBA *rgba = data;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
/* We abuse rgba->alpha to store if we use percentages or numbers */
|
||||
if (gtk_css_token_is (gtk_css_parser_get_token (parser), GTK_CSS_TOKEN_PERCENTAGE))
|
||||
rgba->alpha = 1.0;
|
||||
else
|
||||
rgba->alpha = 0.0;
|
||||
|
||||
if (!parse_color_channel_value (parser, &rgba->red, rgba->alpha != 0.0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (!parse_color_channel_value (parser, &rgba->green, rgba->alpha != 0.0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 2:
|
||||
if (!parse_color_channel_value (parser, &rgba->blue, rgba->alpha != 0.0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 3:
|
||||
if (!gtk_css_parser_consume_number (parser, &rgba->alpha))
|
||||
return 0;
|
||||
|
||||
rgba->alpha = CLAMP (rgba->alpha, 0.0, 1.0);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rgba_init_chars (GdkRGBA *rgba,
|
||||
const char s[8])
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (!g_ascii_isxdigit (s[i]))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rgba->red = (g_ascii_xdigit_value (s[0]) * 16 + g_ascii_xdigit_value (s[1])) / 255.0;
|
||||
rgba->green = (g_ascii_xdigit_value (s[2]) * 16 + g_ascii_xdigit_value (s[3])) / 255.0;
|
||||
rgba->blue = (g_ascii_xdigit_value (s[4]) * 16 + g_ascii_xdigit_value (s[5])) / 255.0;
|
||||
rgba->alpha = (g_ascii_xdigit_value (s[6]) * 16 + g_ascii_xdigit_value (s[7])) / 255.0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
GdkRGBA *rgba)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (gtk_css_token_is_function (token, "rgb"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 3, parse_color_channel, rgba))
|
||||
return FALSE;
|
||||
|
||||
rgba->alpha = 1.0;
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rgba"))
|
||||
{
|
||||
return gtk_css_parser_consume_function (parser, 4, 4, parse_color_channel, rgba);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
|
||||
{
|
||||
const char *s = token->string.string;
|
||||
|
||||
switch (strlen (s))
|
||||
{
|
||||
case 3:
|
||||
if (!rgba_init_chars (rgba, (char[8]) {s[0], s[0], s[1], s[1], s[2], s[2], 'F', 'F' }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (!rgba_init_chars (rgba, (char[8]) {s[0], s[0], s[1], s[1], s[2], s[2], s[3], s[3] }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (!rgba_init_chars (rgba, (char[8]) {s[0], s[1], s[2], s[3], s[4], s[5], 'F', 'F' }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (!rgba_init_chars (rgba, s))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
if (gtk_css_token_is_ident (token, "transparent"))
|
||||
{
|
||||
*rgba = (GdkRGBA) { 0, 0, 0, 0 };
|
||||
}
|
||||
else if (gdk_rgba_parse (rgba, token->string.string))
|
||||
{
|
||||
/* everything's fine */
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", token->string.string);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid color.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010, Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_RGBA_PRIVATE_H__
|
||||
#define __GDK_RGBA_PRIVATE_H__
|
||||
|
||||
#include "gdkrgba.h"
|
||||
|
||||
#include <gtk/css/gtkcss.h>
|
||||
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
|
||||
|
||||
gboolean gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
GdkRGBA *rgba);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (__GTK_CSS_H_INSIDE__) && !defined (GDK_COMPILATION) && !defined (GTK_CSS_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
|
||||
@@ -194,6 +194,10 @@ gdk_vulkan_strerror (VkResult result)
|
||||
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
||||
return "Invalid DRM format modifier plane layout";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 97
|
||||
case VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
|
||||
return "Invalid device address";
|
||||
#endif
|
||||
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
|
||||
+3
-2
@@ -224,7 +224,8 @@ endif
|
||||
# FIXME: might have to add '-xobjective-c' to c_args for quartz backend?
|
||||
libgdk = static_library('gdk',
|
||||
sources: [gdk_sources, gdk_backends_gen_headers, gdkconfig],
|
||||
dependencies: gdk_deps,
|
||||
dependencies: gdk_deps + [libgtk_css_dep],
|
||||
link_with: [libgtk_css, ],
|
||||
include_directories: [confinc, gdkx11_inc, wlinc],
|
||||
c_args: [
|
||||
'-DGDK_COMPILATION',
|
||||
@@ -239,4 +240,4 @@ libgdk = static_library('gdk',
|
||||
libgdk_dep = declare_dependency(
|
||||
sources: ['gdk.h', gdkconfig, gdkenum_h],
|
||||
include_directories: [confinc, gdkx11_inc, wlinc],
|
||||
dependencies: gdk_deps)
|
||||
dependencies: gdk_deps + [libgtk_css_dep])
|
||||
|
||||
@@ -4318,10 +4318,10 @@ gsk_cross_fade_node_draw (GskRenderNode *node,
|
||||
{
|
||||
GskCrossFadeNode *self = (GskCrossFadeNode *) node;
|
||||
|
||||
cairo_push_group (cr);
|
||||
cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
|
||||
gsk_render_node_draw (self->start, cr);
|
||||
|
||||
cairo_push_group (cr);
|
||||
cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
|
||||
gsk_render_node_draw (self->end, cr);
|
||||
|
||||
cairo_pop_group_to_source (cr);
|
||||
|
||||
+257
-2
@@ -1264,8 +1264,8 @@ gsk_transform_unref (GskTransform *self)
|
||||
* @self: (allow-none): a #GskTransform
|
||||
* @string: The string to print into
|
||||
*
|
||||
* Converts @self into a string representation suitable for printing that
|
||||
* can later be parsed with gsk_transform_parse().
|
||||
* Converts @self into a human-readable string representation suitable
|
||||
* for printing that can later be parsed with gsk_transform_parse().
|
||||
**/
|
||||
void
|
||||
gsk_transform_print (GskTransform *self,
|
||||
@@ -1651,3 +1651,258 @@ gsk_transform_transform_bounds (GskTransform *self,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_transform_parse_float (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
float *f = data;
|
||||
double d;
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &d))
|
||||
return 0;
|
||||
|
||||
f[n] = d;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_transform_parse_scale (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
float *f = data;
|
||||
double d;
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &d))
|
||||
return 0;
|
||||
|
||||
f[n] = d;
|
||||
f[1] = d;
|
||||
return 1;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_transform_parser_parse (GtkCssParser *parser,
|
||||
GskTransform **out_transform)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
GskTransform *transform = NULL;
|
||||
float f[16] = { 0, };
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (gtk_css_token_is_ident (token, "none"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*out_transform = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (gtk_css_token_is_function (token, "matrix"))
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
if (!gtk_css_parser_consume_function (parser, 6, 6, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
graphene_matrix_init_from_2d (&matrix, f[0], f[1], f[2], f[3], f[4], f[5]);
|
||||
transform = gsk_transform_matrix_with_category (transform,
|
||||
&matrix,
|
||||
GSK_TRANSFORM_CATEGORY_2D);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "matrix3d"))
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
if (!gtk_css_parser_consume_function (parser, 16, 16, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
graphene_matrix_init_from_float (&matrix, f);
|
||||
transform = gsk_transform_matrix (transform, &matrix);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "perspective"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_perspective (transform, f[0]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rotate") ||
|
||||
gtk_css_token_is_function (token, "rotateZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_rotate (transform, f[0]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rotate3d"))
|
||||
{
|
||||
graphene_vec3_t axis;
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 4, 4, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
graphene_vec3_init (&axis, f[0], f[1], f[2]);
|
||||
transform = gsk_transform_rotate_3d (transform, f[3], &axis);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rotateX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_rotate_3d (transform, f[0], graphene_vec3_x_axis ());
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "rotateY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_rotate_3d (transform, f[0], graphene_vec3_y_axis ());
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scale"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 2, gsk_transform_parse_scale, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale (transform, f[0], f[1]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scale3d"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 3, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale_3d (transform, f[0], f[1], f[2]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scaleX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale (transform, f[0], 1.f);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scaleY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale (transform, 1.f, f[0]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "scaleZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_scale_3d (transform, 1.f, 1.f, f[0]);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translate"))
|
||||
{
|
||||
f[1] = 0.f;
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 2, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (f[0], f[1]));
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translate3d"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 3, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (f[0], f[1], f[2]));
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translateX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (f[0], 0.f));
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translateY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (0.f, f[0]));
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "translateZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0.f, 0.f, f[0]));
|
||||
}
|
||||
#if 0
|
||||
/* FIXME: add these */
|
||||
else if (gtk_css_token_is_function (token, "skew"))
|
||||
{
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "skewX"))
|
||||
{
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "skewY"))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
}
|
||||
|
||||
if (transform == NULL)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a transform");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*out_transform = transform;
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
gsk_transform_unref (transform);
|
||||
*out_transform = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_transform_parse:
|
||||
* @string: the string to parse
|
||||
* @out_transform: (out): The location to put the transform in
|
||||
*
|
||||
* Parses the given @string into a transform and puts it in
|
||||
* @out_transform. Strings printed via gsk_transform_to_string()
|
||||
* can be read in again successfully using this function.
|
||||
*
|
||||
* If @string does not describe a valid transform, %FALSE is
|
||||
* returned and %NULL is put in @out_transform.
|
||||
*
|
||||
* Returns: %TRUE if @string described a valid transform.
|
||||
**/
|
||||
gboolean
|
||||
gsk_transform_parse (const char *string,
|
||||
GskTransform **out_transform)
|
||||
{
|
||||
GtkCssParser *parser;
|
||||
GBytes *bytes;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (string != NULL, FALSE);
|
||||
g_return_val_if_fail (out_transform != NULL, FALSE);
|
||||
|
||||
bytes = g_bytes_new_static (string, strlen (string));
|
||||
parser = gtk_css_parser_new_for_bytes (bytes, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
result = gsk_transform_parser_parse (parser, out_transform);
|
||||
|
||||
if (result && !gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
g_clear_pointer (out_transform, gsk_transform_unref);
|
||||
result = FALSE;
|
||||
}
|
||||
gtk_css_parser_unref (parser);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ void gsk_transform_print (GskTransform
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
char * gsk_transform_to_string (GskTransform *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gsk_transform_parse (const char *string,
|
||||
GskTransform **out_transform);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gsk_transform_to_matrix (GskTransform *self,
|
||||
graphene_matrix_t *out_matrix);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -23,15 +23,21 @@
|
||||
|
||||
#include "gsktransform.h"
|
||||
|
||||
#include <gsk/gsk.h>
|
||||
#include "gsk/gskrendernodeprivate.h"
|
||||
|
||||
#include <gtk/css/gtkcss.h>
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskTransform * gsk_transform_matrix_with_category (GskTransform *next,
|
||||
const graphene_matrix_t*matrix,
|
||||
GskTransformCategory category);
|
||||
|
||||
gboolean gsk_transform_parser_parse (GtkCssParser *parser,
|
||||
GskTransform **out_transform);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_TRANSFORM_PRIVATE_H__ */
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_H__
|
||||
#define __GTK_CSS_H__
|
||||
|
||||
#define __GTK_CSS_H_INSIDE__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
#include <gtk/css/gtkcssenums.h>
|
||||
#include <gtk/css/gtkcssenumtypes.h>
|
||||
#include <gtk/css/gtkcsserror.h>
|
||||
#include <gtk/css/gtkcsslocation.h>
|
||||
#include <gtk/css/gtkcsssection.h>
|
||||
|
||||
#undef __GTK_CSS_H_INSIDE__
|
||||
|
||||
#endif /* __GTK_CSS_H__ */
|
||||
@@ -0,0 +1,77 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_ENUMS_H__
|
||||
#define __GTK_CSS_ENUMS_H__
|
||||
|
||||
#if !defined (__GTK_CSS_H_INSIDE__) && !defined (GTK_CSS_COMPILATION)
|
||||
#error "Only <gtk/css/gtkcss.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
/**
|
||||
* GtkCssParserError:
|
||||
* @GTK_CSS_PARSER_ERROR_FAILED: Unknown failure.
|
||||
* @GTK_CSS_PARSER_ERROR_SYNTAX: The given text does not form valid
|
||||
* syntax
|
||||
* @GTK_CSS_PARSER_ERROR_IMPORT: Failed to import a resource
|
||||
* @GTK_CSS_PARSER_ERROR_NAME: The given name has not been defined
|
||||
* @GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE: The given value is not
|
||||
* correct
|
||||
*
|
||||
* Errors that can occur while parsing CSS.
|
||||
*
|
||||
* These errors are unexpected and will cause parts of the given CSS
|
||||
* to be ignored.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_PARSER_ERROR_FAILED,
|
||||
GTK_CSS_PARSER_ERROR_SYNTAX,
|
||||
GTK_CSS_PARSER_ERROR_IMPORT,
|
||||
GTK_CSS_PARSER_ERROR_NAME,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
|
||||
} GtkCssParserError;
|
||||
|
||||
/**
|
||||
* GtkCssParserWarning:
|
||||
* @GTK_CSS_PARSER_WARNING_DEPRECATED: The given construct is
|
||||
* deprecated and will be removed in a future version
|
||||
* @GTK_CSS_PARSER_WARNING_SYNTAX: A syntax construct was used
|
||||
* that should be avoided
|
||||
*
|
||||
* Warnings that can occur while parsing CSS.
|
||||
*
|
||||
* Unlike #GtkCssParserErrors, warnings do not cause the parser to
|
||||
* skip any input, but they indicate issues that should be fixed.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_PARSER_WARNING_DEPRECATED,
|
||||
GTK_CSS_PARSER_WARNING_SYNTAX
|
||||
} GtkCssParserWarning;
|
||||
|
||||
#endif /* __GTK_CSS_ENUMS_H__ */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#include "config.h"
|
||||
#include "gtkcssenumtypes.h"
|
||||
#include <gtkcss.h>
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@basename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN value-production ***/
|
||||
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
|
||||
/*** END value-production ***/
|
||||
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType g_define_type_id =
|
||||
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
|
||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
||||
}
|
||||
|
||||
return g_define_type_id__volatile;
|
||||
}
|
||||
|
||||
/*** END value-tail ***/
|
||||
@@ -0,0 +1,29 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#ifndef __GTK_CSS_ENUM_TYPES_H__
|
||||
#define __GTK_CSS_ENUM_TYPES_H__
|
||||
|
||||
#if !defined (__GTK_CSS_H_INSIDE__) && !defined (GTK_CSS_COMPILATION)
|
||||
#error "Only <gtk/css/gtkcss.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
|
||||
/* enumerations from "@basename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GDK_AVAILABLE_IN_ALL GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_ENUM_TYPES_H__ */
|
||||
/*** END file-tail ***/
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsserror.h"
|
||||
|
||||
GQuark
|
||||
gtk_css_parser_error_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-css-parser-error-quark");
|
||||
}
|
||||
|
||||
GQuark
|
||||
gtk_css_parser_warning_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-css-parser-warning-quark");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GTK_CSS_ERROR_H__
|
||||
#define __GTK_CSS_ERROR_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
/**
|
||||
* GTK_CSS_PARSER_ERROR:
|
||||
*
|
||||
* Domain for #GtkCssParser errors.
|
||||
*/
|
||||
#define GTK_CSS_PARSER_ERROR (gtk_css_parser_error_quark ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GQuark gtk_css_parser_error_quark (void);
|
||||
|
||||
/**
|
||||
* GTK_CSS_PARSER_WARNING:
|
||||
*
|
||||
* Domain for #GtkCssParser warnings.
|
||||
*/
|
||||
#define GTK_CSS_PARSER_WARNING (gtk_css_parser_warning_quark ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GQuark gtk_css_parser_warning_quark (void);
|
||||
|
||||
#endif /* __GTK_CSS_ERROR_H__ */
|
||||
@@ -0,0 +1,74 @@
|
||||
/* GSK - The GIMP Toolkit
|
||||
* Copyright (C) 2019 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsslocationprivate.h"
|
||||
|
||||
/**
|
||||
* GtkCssLocation:
|
||||
* @bytes: number of bytes parsed since the beginning
|
||||
* @chars: number of characters parsed since the beginning
|
||||
* @lines: number of full lines that have been parsed
|
||||
* If you want to display this as a line number, you
|
||||
* need to add 1 to this.
|
||||
* @line_bytes: Number of bytes parsed since the last line break
|
||||
* @line_chars: Number of characters parsed since the last line
|
||||
* break
|
||||
*
|
||||
* @GtkCssLocation is used to present a location in a file - or other
|
||||
* source of data parsed by the CSS engine.
|
||||
*
|
||||
* The @bytes and @line_bytes offsets are meant to be used to
|
||||
* programmatically match data. The @lines and @line_chars offsets
|
||||
* can be used for printing the location in a file.
|
||||
*
|
||||
* Note that the @lines parameter starts from 0 and is increased
|
||||
* whenever a CSS line break is encountered. (CSS defines the C character
|
||||
* sequences "\r\n", "\r", "\n" and "\f" as newlines.)
|
||||
* If your document uses different rules for line breaking, you might want
|
||||
* run into problems here.
|
||||
*/
|
||||
|
||||
void
|
||||
gtk_css_location_init (GtkCssLocation *location)
|
||||
{
|
||||
memset (location, 0, sizeof (GtkCssLocation));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_location_advance (GtkCssLocation *location,
|
||||
gsize bytes,
|
||||
gsize chars)
|
||||
{
|
||||
location->bytes += bytes;
|
||||
location->chars += chars;
|
||||
location->line_bytes += bytes;
|
||||
location->line_chars += chars;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_location_advance_newline (GtkCssLocation *location,
|
||||
gboolean is_windows)
|
||||
{
|
||||
gtk_css_location_advance (location, is_windows ? 2 : 1, is_windows ? 2 : 1);
|
||||
|
||||
location->lines++;
|
||||
location->line_bytes = 0;
|
||||
location->line_chars = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/* GSK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_LOCATION_H__
|
||||
#define __GTK_CSS_LOCATION_H__
|
||||
|
||||
#if !defined (__GTK_CSS_H_INSIDE__) && !defined (GTK_CSS_COMPILATION)
|
||||
#error "Only <gtk/css/gtkcss.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkCssLocation GtkCssLocation;
|
||||
|
||||
struct _GtkCssLocation
|
||||
{
|
||||
gsize bytes;
|
||||
gsize chars;
|
||||
gsize lines;
|
||||
gsize line_bytes;
|
||||
gsize line_chars;
|
||||
};
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_LOCATION_H__ */
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GTK_CSS_LOCATION_PRIVATE_H__
|
||||
#define __GTK_CSS_LOCATION_PRIVATE_H__
|
||||
|
||||
#include "gtkcsslocation.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gtk_css_location_init (GtkCssLocation *location);
|
||||
|
||||
void gtk_css_location_advance (GtkCssLocation *location,
|
||||
gsize bytes,
|
||||
gsize chars);
|
||||
void gtk_css_location_advance_newline (GtkCssLocation *location,
|
||||
gboolean is_windows);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_LOCATION_PRIVATE_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GTK_CSS_PARSER_H__
|
||||
#define __GTK_CSS_PARSER_H__
|
||||
|
||||
#include "gtkcssenums.h"
|
||||
#include "gtkcsstokenizerprivate.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkCssParser GtkCssParser;
|
||||
|
||||
typedef struct _GtkCssParseOption GtkCssParseOption;
|
||||
|
||||
struct _GtkCssParseOption
|
||||
{
|
||||
gboolean (* can_parse) (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer user_data);
|
||||
gboolean (* parse) (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer user_data);
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
typedef void (* GtkCssParserErrorFunc) (GtkCssParser *parser,
|
||||
const GtkCssLocation *start,
|
||||
const GtkCssLocation *end,
|
||||
const GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
GtkCssParser * gtk_css_parser_new_for_file (GFile *file,
|
||||
GtkCssParserErrorFunc error_func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy,
|
||||
GError **error);
|
||||
GtkCssParser * gtk_css_parser_new_for_bytes (GBytes *bytes,
|
||||
GFile *file,
|
||||
GFile *base_directory,
|
||||
GtkCssParserErrorFunc error_func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy);
|
||||
GtkCssParser * gtk_css_parser_ref (GtkCssParser *self);
|
||||
void gtk_css_parser_unref (GtkCssParser *self);
|
||||
|
||||
GFile * gtk_css_parser_get_file (GtkCssParser *self);
|
||||
GFile * gtk_css_parser_resolve_url (GtkCssParser *self,
|
||||
const char *url);
|
||||
|
||||
const GtkCssLocation * gtk_css_parser_get_start_location (GtkCssParser *self);
|
||||
const GtkCssLocation * gtk_css_parser_get_end_location (GtkCssParser *self);
|
||||
const GtkCssLocation * gtk_css_parser_get_block_location (GtkCssParser *self);
|
||||
|
||||
const GtkCssToken * gtk_css_parser_peek_token (GtkCssParser *self);
|
||||
const GtkCssToken * gtk_css_parser_get_token (GtkCssParser *self);
|
||||
void gtk_css_parser_consume_token (GtkCssParser *self);
|
||||
|
||||
void gtk_css_parser_start_block (GtkCssParser *self);
|
||||
void gtk_css_parser_start_semicolon_block (GtkCssParser *self,
|
||||
GtkCssTokenType alternative_token);
|
||||
void gtk_css_parser_end_block_prelude (GtkCssParser *self);
|
||||
void gtk_css_parser_end_block (GtkCssParser *self);
|
||||
void gtk_css_parser_skip (GtkCssParser *self);
|
||||
void gtk_css_parser_skip_until (GtkCssParser *self,
|
||||
GtkCssTokenType token_type);
|
||||
|
||||
void gtk_css_parser_emit_error (GtkCssParser *self,
|
||||
const GtkCssLocation *start,
|
||||
const GtkCssLocation *end,
|
||||
const GError *error);
|
||||
void gtk_css_parser_error (GtkCssParser *self,
|
||||
GtkCssParserError code,
|
||||
const GtkCssLocation *start,
|
||||
const GtkCssLocation *end,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(5, 6);
|
||||
void gtk_css_parser_error_syntax (GtkCssParser *self,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
void gtk_css_parser_error_value (GtkCssParser *self,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
void gtk_css_parser_error_import (GtkCssParser *self,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
void gtk_css_parser_warn (GtkCssParser *self,
|
||||
GtkCssParserWarning code,
|
||||
const GtkCssLocation *start,
|
||||
const GtkCssLocation *end,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(5, 6);
|
||||
void gtk_css_parser_warn_syntax (GtkCssParser *self,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
|
||||
gboolean gtk_css_parser_has_token (GtkCssParser *self,
|
||||
GtkCssTokenType token_type);
|
||||
gboolean gtk_css_parser_has_ident (GtkCssParser *self,
|
||||
const char *ident);
|
||||
gboolean gtk_css_parser_has_integer (GtkCssParser *self);
|
||||
gboolean gtk_css_parser_has_function (GtkCssParser *self,
|
||||
const char *name);
|
||||
|
||||
gboolean gtk_css_parser_try_delim (GtkCssParser *self,
|
||||
gunichar codepoint);
|
||||
gboolean gtk_css_parser_try_ident (GtkCssParser *self,
|
||||
const char *ident);
|
||||
gboolean gtk_css_parser_try_at_keyword (GtkCssParser *self,
|
||||
const char *keyword);
|
||||
gboolean gtk_css_parser_try_token (GtkCssParser *self,
|
||||
GtkCssTokenType token_type);
|
||||
|
||||
char * gtk_css_parser_consume_ident (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT;
|
||||
char * gtk_css_parser_consume_string (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GFile * gtk_css_parser_consume_url (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean gtk_css_parser_consume_number (GtkCssParser *self,
|
||||
double *number);
|
||||
gboolean gtk_css_parser_consume_integer (GtkCssParser *self,
|
||||
int *number);
|
||||
gboolean gtk_css_parser_consume_percentage (GtkCssParser *self,
|
||||
double *number);
|
||||
gboolean gtk_css_parser_consume_function (GtkCssParser *self,
|
||||
guint min_args,
|
||||
guint max_args,
|
||||
guint (* parse_func) (GtkCssParser *, guint, gpointer),
|
||||
gpointer data);
|
||||
gsize gtk_css_parser_consume_any (GtkCssParser *parser,
|
||||
const GtkCssParseOption *options,
|
||||
gsize n_options,
|
||||
gpointer user_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_PARSER_H__ */
|
||||
@@ -0,0 +1,253 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsssection.h"
|
||||
|
||||
#include "gtkcssparserprivate.h"
|
||||
|
||||
struct _GtkCssSection
|
||||
{
|
||||
gint ref_count;
|
||||
GtkCssSection *parent;
|
||||
GFile *file;
|
||||
GtkCssLocation start_location;
|
||||
GtkCssLocation end_location; /* end location if parser is %NULL */
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GtkCssSection, gtk_css_section, gtk_css_section_ref, gtk_css_section_unref)
|
||||
|
||||
/**
|
||||
* gtk_css_section_new: (constructor)
|
||||
* @file: (nullable) (transfer none): The file this section refers to
|
||||
* @start: The start location
|
||||
* @end: The end location
|
||||
*
|
||||
* Creates a new #GtkCssSection referring to the section
|
||||
* in the given @file from the @start location to the
|
||||
* @end location.
|
||||
*
|
||||
* Returns: a new #GtkCssSection
|
||||
**/
|
||||
GtkCssSection *
|
||||
gtk_css_section_new (GFile *file,
|
||||
const GtkCssLocation *start,
|
||||
const GtkCssLocation *end)
|
||||
{
|
||||
GtkCssSection *result;
|
||||
|
||||
g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
|
||||
g_return_val_if_fail (start != NULL, NULL);
|
||||
g_return_val_if_fail (end != NULL, NULL);
|
||||
|
||||
result = g_slice_new0 (GtkCssSection);
|
||||
|
||||
result->ref_count = 1;
|
||||
if (file)
|
||||
result->file = g_object_ref (file);
|
||||
result->start_location = *start;
|
||||
result->end_location = *end;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_ref:
|
||||
* @section: a #GtkCssSection
|
||||
*
|
||||
* Increments the reference count on @section.
|
||||
*
|
||||
* Returns: @section itself.
|
||||
**/
|
||||
GtkCssSection *
|
||||
gtk_css_section_ref (GtkCssSection *section)
|
||||
{
|
||||
g_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
section->ref_count += 1;
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_unref:
|
||||
* @section: a #GtkCssSection
|
||||
*
|
||||
* Decrements the reference count on @section, freeing the
|
||||
* structure if the reference count reaches 0.
|
||||
**/
|
||||
void
|
||||
gtk_css_section_unref (GtkCssSection *section)
|
||||
{
|
||||
g_return_if_fail (section != NULL);
|
||||
|
||||
section->ref_count -= 1;
|
||||
if (section->ref_count > 0)
|
||||
return;
|
||||
|
||||
if (section->parent)
|
||||
gtk_css_section_unref (section->parent);
|
||||
if (section->file)
|
||||
g_object_unref (section->file);
|
||||
|
||||
g_slice_free (GtkCssSection, section);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_parent:
|
||||
* @section: the section
|
||||
*
|
||||
* Gets the parent section for the given @section. The parent section is
|
||||
* the section that contains this @section. A special case are sections of
|
||||
* type #GTK_CSS_SECTION_DOCUMENT. Their parent will either be %NULL
|
||||
* if they are the original CSS document that was loaded by
|
||||
* gtk_css_provider_load_from_file() or a section of type
|
||||
* #GTK_CSS_SECTION_IMPORT if it was loaded with an import rule from
|
||||
* a different file.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the parent section or %NULL if none
|
||||
**/
|
||||
GtkCssSection *
|
||||
gtk_css_section_get_parent (const GtkCssSection *section)
|
||||
{
|
||||
g_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
return section->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_file:
|
||||
* @section: the section
|
||||
*
|
||||
* Gets the file that @section was parsed from. If no such file exists,
|
||||
* for example because the CSS was loaded via
|
||||
* @gtk_css_provider_load_from_data(), then %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer none): the #GFile that @section was parsed from
|
||||
* or %NULL if @section was parsed from other data
|
||||
**/
|
||||
GFile *
|
||||
gtk_css_section_get_file (const GtkCssSection *section)
|
||||
{
|
||||
g_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
return section->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_start_location:
|
||||
* @section: the section
|
||||
*
|
||||
* Returns the location in the CSS document where this section starts.
|
||||
*
|
||||
* Returns: (tranfer none) (not nullable): The start location of
|
||||
* this section
|
||||
**/
|
||||
const GtkCssLocation *
|
||||
gtk_css_section_get_start_location (const GtkCssSection *section)
|
||||
{
|
||||
g_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
return §ion->start_location;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_end_location:
|
||||
* @section: the section
|
||||
*
|
||||
* Returns the location in the CSS document where this section ends.
|
||||
*
|
||||
* Returns: (tranfer none) (not nullable): The end location of
|
||||
* this section
|
||||
**/
|
||||
const GtkCssLocation *
|
||||
gtk_css_section_get_end_location (const GtkCssSection *section)
|
||||
{
|
||||
g_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
return §ion->end_location;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_print:
|
||||
* @section: a section
|
||||
* @string: a #GString to print to
|
||||
*
|
||||
* Prints the @section into @string in a human-readable form. This
|
||||
* is a form like `gtk.css:32:1-23` to denote line 32, characters
|
||||
* 1 to 23 in the file gtk.css.
|
||||
**/
|
||||
void
|
||||
gtk_css_section_print (const GtkCssSection *section,
|
||||
GString *string)
|
||||
{
|
||||
if (section->file)
|
||||
{
|
||||
GFileInfo *info;
|
||||
|
||||
info = g_file_query_info (section->file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0, NULL, NULL);
|
||||
|
||||
if (info)
|
||||
{
|
||||
g_string_append (string, g_file_info_get_display_name (info));
|
||||
g_object_unref (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append (string, "<broken file>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append (string, "<data>");
|
||||
}
|
||||
|
||||
g_string_append_printf (string, ":%zu:%zu",
|
||||
section->start_location.lines + 1,
|
||||
section->start_location.line_chars + 1);
|
||||
if (section->start_location.lines != section->end_location.lines ||
|
||||
section->start_location.line_chars != section->end_location.line_chars)
|
||||
{
|
||||
g_string_append (string, "-");
|
||||
if (section->start_location.lines != section->end_location.lines)
|
||||
g_string_append_printf (string, "%zu:", section->end_location.lines + 1);
|
||||
g_string_append_printf (string, "%zu", section->end_location.line_chars + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_to_string:
|
||||
* @section: a #GtkCssSection
|
||||
*
|
||||
* Prints the section into a human-readable text form using
|
||||
* gtk_css_section_print().
|
||||
*
|
||||
* Returns: (transfer full): A new string.
|
||||
**/
|
||||
char *
|
||||
gtk_css_section_to_string (const GtkCssSection *section)
|
||||
{
|
||||
GString *string;
|
||||
|
||||
g_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
gtk_css_section_print (section, string);
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
@@ -18,49 +18,18 @@
|
||||
#ifndef __GTK_CSS_SECTION_H__
|
||||
#define __GTK_CSS_SECTION_H__
|
||||
|
||||
#if !defined (__GTK_CSS_H_INSIDE__) && !defined (GTK_CSS_COMPILATION)
|
||||
#error "Only <gtk/css/gtkcss.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gtk/css/gtkcsslocation.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_SECTION (gtk_css_section_get_type ())
|
||||
|
||||
/**
|
||||
* GtkCssSectionType:
|
||||
* @GTK_CSS_SECTION_DOCUMENT: The section describes a complete document.
|
||||
* This section time is the only one where gtk_css_section_get_parent()
|
||||
* might return %NULL.
|
||||
* @GTK_CSS_SECTION_IMPORT: The section defines an import rule.
|
||||
* @GTK_CSS_SECTION_COLOR_DEFINITION: The section defines a color. This
|
||||
* is a GTK extension to CSS.
|
||||
* @GTK_CSS_SECTION_RULESET: The section defines a CSS ruleset.
|
||||
* @GTK_CSS_SECTION_SELECTOR: The section defines a CSS selector.
|
||||
* @GTK_CSS_SECTION_DECLARATION: The section defines the declaration of
|
||||
* a CSS variable.
|
||||
* @GTK_CSS_SECTION_VALUE: The section defines the value of a CSS declaration.
|
||||
* @GTK_CSS_SECTION_KEYFRAMES: The section defines keyframes. See [CSS
|
||||
* Animations](http://dev.w3.org/csswg/css3-animations/#keyframes) for details
|
||||
*
|
||||
* The different types of sections indicate parts of a CSS document as
|
||||
* parsed by GTK’s CSS parser. They are oriented towards the
|
||||
* [CSS Grammar](http://www.w3.org/TR/CSS21/grammar.html),
|
||||
* but may contain extensions.
|
||||
*
|
||||
* More types might be added in the future as the parser incorporates
|
||||
* more features.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_SECTION_DOCUMENT,
|
||||
GTK_CSS_SECTION_IMPORT,
|
||||
GTK_CSS_SECTION_COLOR_DEFINITION,
|
||||
GTK_CSS_SECTION_RULESET,
|
||||
GTK_CSS_SECTION_SELECTOR,
|
||||
GTK_CSS_SECTION_DECLARATION,
|
||||
GTK_CSS_SECTION_VALUE,
|
||||
GTK_CSS_SECTION_KEYFRAMES
|
||||
} GtkCssSectionType;
|
||||
|
||||
/**
|
||||
* GtkCssSection:
|
||||
*
|
||||
@@ -73,25 +42,31 @@ typedef struct _GtkCssSection GtkCssSection;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_css_section_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkCssSection * gtk_css_section_new (GFile *file,
|
||||
const GtkCssLocation *start,
|
||||
const GtkCssLocation *end);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkCssSection * gtk_css_section_ref (GtkCssSection *section);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_css_section_unref (GtkCssSection *section);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkCssSectionType gtk_css_section_get_section_type (const GtkCssSection *section);
|
||||
void gtk_css_section_print (const GtkCssSection *section,
|
||||
GString *string);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
char * gtk_css_section_to_string (const GtkCssSection *section);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkCssSection * gtk_css_section_get_parent (const GtkCssSection *section);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GFile * gtk_css_section_get_file (const GtkCssSection *section);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gtk_css_section_get_start_line (const GtkCssSection *section);
|
||||
const GtkCssLocation *
|
||||
gtk_css_section_get_start_location (const GtkCssSection *section);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gtk_css_section_get_start_position (const GtkCssSection *section);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gtk_css_section_get_end_line (const GtkCssSection *section);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gtk_css_section_get_end_position (const GtkCssSection *section);
|
||||
const GtkCssLocation *
|
||||
gtk_css_section_get_end_location (const GtkCssSection *section);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,140 @@
|
||||
/* GSK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_TOKENIZER_PRIVATE_H__
|
||||
#define __GTK_CSS_TOKENIZER_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <gtk/css/gtkcsslocation.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
/* no content */
|
||||
GTK_CSS_TOKEN_EOF,
|
||||
GTK_CSS_TOKEN_WHITESPACE,
|
||||
GTK_CSS_TOKEN_OPEN_PARENS,
|
||||
GTK_CSS_TOKEN_CLOSE_PARENS,
|
||||
GTK_CSS_TOKEN_OPEN_SQUARE,
|
||||
GTK_CSS_TOKEN_CLOSE_SQUARE,
|
||||
GTK_CSS_TOKEN_OPEN_CURLY,
|
||||
GTK_CSS_TOKEN_CLOSE_CURLY,
|
||||
GTK_CSS_TOKEN_COMMA,
|
||||
GTK_CSS_TOKEN_COLON,
|
||||
GTK_CSS_TOKEN_SEMICOLON,
|
||||
GTK_CSS_TOKEN_CDO,
|
||||
GTK_CSS_TOKEN_CDC,
|
||||
GTK_CSS_TOKEN_INCLUDE_MATCH,
|
||||
GTK_CSS_TOKEN_DASH_MATCH,
|
||||
GTK_CSS_TOKEN_PREFIX_MATCH,
|
||||
GTK_CSS_TOKEN_SUFFIX_MATCH,
|
||||
GTK_CSS_TOKEN_SUBSTRING_MATCH,
|
||||
GTK_CSS_TOKEN_COLUMN,
|
||||
GTK_CSS_TOKEN_BAD_STRING,
|
||||
GTK_CSS_TOKEN_BAD_URL,
|
||||
GTK_CSS_TOKEN_COMMENT,
|
||||
/* delim */
|
||||
GTK_CSS_TOKEN_DELIM,
|
||||
/* string */
|
||||
GTK_CSS_TOKEN_STRING,
|
||||
GTK_CSS_TOKEN_IDENT,
|
||||
GTK_CSS_TOKEN_FUNCTION,
|
||||
GTK_CSS_TOKEN_AT_KEYWORD,
|
||||
GTK_CSS_TOKEN_HASH_UNRESTRICTED,
|
||||
GTK_CSS_TOKEN_HASH_ID,
|
||||
GTK_CSS_TOKEN_URL,
|
||||
/* number */
|
||||
GTK_CSS_TOKEN_SIGNED_INTEGER,
|
||||
GTK_CSS_TOKEN_SIGNLESS_INTEGER,
|
||||
GTK_CSS_TOKEN_SIGNED_NUMBER,
|
||||
GTK_CSS_TOKEN_SIGNLESS_NUMBER,
|
||||
GTK_CSS_TOKEN_PERCENTAGE,
|
||||
/* dimension */
|
||||
GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION,
|
||||
GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION,
|
||||
GTK_CSS_TOKEN_DIMENSION
|
||||
} GtkCssTokenType;
|
||||
|
||||
typedef union _GtkCssToken GtkCssToken;
|
||||
typedef struct _GtkCssTokenizer GtkCssTokenizer;
|
||||
|
||||
typedef struct _GtkCssStringToken GtkCssStringToken;
|
||||
typedef struct _GtkCssDelimToken GtkCssDelimToken;
|
||||
typedef struct _GtkCssNumberToken GtkCssNumberToken;
|
||||
typedef struct _GtkCssDimensionToken GtkCssDimensionToken;
|
||||
|
||||
struct _GtkCssStringToken {
|
||||
GtkCssTokenType type;
|
||||
char *string;
|
||||
};
|
||||
|
||||
struct _GtkCssDelimToken {
|
||||
GtkCssTokenType type;
|
||||
gunichar delim;
|
||||
};
|
||||
|
||||
struct _GtkCssNumberToken {
|
||||
GtkCssTokenType type;
|
||||
double number;
|
||||
};
|
||||
|
||||
struct _GtkCssDimensionToken {
|
||||
GtkCssTokenType type;
|
||||
double value;
|
||||
char *dimension;
|
||||
};
|
||||
|
||||
union _GtkCssToken {
|
||||
GtkCssTokenType type;
|
||||
GtkCssStringToken string;
|
||||
GtkCssDelimToken delim;
|
||||
GtkCssNumberToken number;
|
||||
GtkCssDimensionToken dimension;
|
||||
};
|
||||
|
||||
void gtk_css_token_clear (GtkCssToken *token);
|
||||
|
||||
gboolean gtk_css_token_is_finite (const GtkCssToken *token);
|
||||
gboolean gtk_css_token_is_preserved (const GtkCssToken *token,
|
||||
GtkCssTokenType *out_closing);
|
||||
#define gtk_css_token_is(token, _type) ((token)->type == (_type))
|
||||
gboolean gtk_css_token_is_ident (const GtkCssToken *token,
|
||||
const char *ident);
|
||||
gboolean gtk_css_token_is_function (const GtkCssToken *token,
|
||||
const char *ident);
|
||||
gboolean gtk_css_token_is_delim (const GtkCssToken *token,
|
||||
gunichar delim);
|
||||
|
||||
void gtk_css_token_print (const GtkCssToken *token,
|
||||
GString *string);
|
||||
char * gtk_css_token_to_string (const GtkCssToken *token);
|
||||
|
||||
GtkCssTokenizer * gtk_css_tokenizer_new (GBytes *bytes);
|
||||
|
||||
GtkCssTokenizer * gtk_css_tokenizer_ref (GtkCssTokenizer *tokenizer);
|
||||
void gtk_css_tokenizer_unref (GtkCssTokenizer *tokenizer);
|
||||
|
||||
const GtkCssLocation * gtk_css_tokenizer_get_location (GtkCssTokenizer *tokenizer);
|
||||
|
||||
gboolean gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
|
||||
GtkCssToken *token,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_TOKENIZER_PRIVATE_H__ */
|
||||
@@ -0,0 +1,57 @@
|
||||
gtk_css_public_sources = files([
|
||||
'gtkcsslocation.c',
|
||||
'gtkcsserror.c',
|
||||
'gtkcsssection.c',
|
||||
])
|
||||
|
||||
gtk_css_private_sources = files([
|
||||
'gtkcssparser.c',
|
||||
'gtkcsstokenizer.c',
|
||||
])
|
||||
|
||||
gtk_css_public_headers = files([
|
||||
'gtkcssenums.h',
|
||||
'gtkcsserror.h',
|
||||
'gtkcsslocation.h',
|
||||
'gtkcsssection.h',
|
||||
])
|
||||
|
||||
install_headers(gtk_css_public_headers, 'gtkcss.h', subdir: 'gtk-4.0/gtk/css')
|
||||
|
||||
gtk_css_deps = [
|
||||
libm,
|
||||
glib_dep,
|
||||
gobject_dep,
|
||||
platform_gio_dep,
|
||||
]
|
||||
|
||||
gtk_css_enums = gnome.mkenums('gtkcssenumtypes',
|
||||
sources: gtk_css_public_headers,
|
||||
c_template: 'gtkcssenumtypes.c.template',
|
||||
h_template: 'gtkcssenumtypes.h.template',
|
||||
install_dir: join_paths(gtk_includedir, 'gtk-4.0/gtk/css'),
|
||||
install_header: true)
|
||||
|
||||
gtk_css_enum_h = gtk_css_enums[1]
|
||||
|
||||
libgtk_css = static_library('gtk_css',
|
||||
sources: [
|
||||
gtk_css_public_sources,
|
||||
gtk_css_private_sources,
|
||||
gtk_css_enums,
|
||||
],
|
||||
dependencies: gtk_css_deps,
|
||||
include_directories: [ confinc, ],
|
||||
c_args: [
|
||||
'-DGTK_CSS_COMPILATION',
|
||||
'-DG_LOG_DOMAIN="Gtk"',
|
||||
'-DG_LOG_STRUCTURED=1',
|
||||
] + common_cflags,
|
||||
link_args: common_ldflags)
|
||||
|
||||
# We don't have link_with: to internal static libs here on purpose, just
|
||||
# list the dependencies and generated headers and such, for use in the
|
||||
# "public" libgtk_dep used by internal executables.
|
||||
libgtk_css_dep = declare_dependency(include_directories: [ confinc, ],
|
||||
sources: [ gtk_css_enum_h ],
|
||||
dependencies: gtk_css_deps)
|
||||
@@ -27,7 +27,10 @@
|
||||
|
||||
#define __GTK_H_INSIDE__
|
||||
|
||||
#include <gtk/css/gtkcss.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gsk/gsk.h>
|
||||
|
||||
#include <gtk/gtkaboutdialog.h>
|
||||
#include <gtk/gtkaccelgroup.h>
|
||||
#include <gtk/gtkaccellabel.h>
|
||||
@@ -81,7 +84,6 @@
|
||||
#include <gtk/gtkcomboboxtext.h>
|
||||
#include <gtk/gtkcontainer.h>
|
||||
#include <gtk/gtkcssprovider.h>
|
||||
#include <gtk/gtkcsssection.h>
|
||||
#include <gtk/gtkcustomlayout.h>
|
||||
#include <gtk/gtkdebug.h>
|
||||
#include <gtk/gtkdialog.h>
|
||||
|
||||
@@ -199,17 +199,6 @@ get_spacing (GtkBoxLayout *self,
|
||||
return css_spacing + self->spacing;
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_box_layout_get_request_mode (GtkLayoutManager *layout_manager,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkBoxLayout *self = GTK_BOX_LAYOUT (layout_manager);
|
||||
|
||||
return self->orientation == GTK_ORIENTATION_HORIZONTAL
|
||||
? GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT
|
||||
: GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_layout_compute_size (GtkBoxLayout *self,
|
||||
GtkWidget *widget,
|
||||
@@ -713,7 +702,6 @@ gtk_box_layout_class_init (GtkBoxLayoutClass *klass)
|
||||
gobject_class->set_property = gtk_box_layout_set_property;
|
||||
gobject_class->get_property = gtk_box_layout_get_property;
|
||||
|
||||
layout_manager_class->get_request_mode = gtk_box_layout_get_request_mode;
|
||||
layout_manager_class->measure = gtk_box_layout_measure;
|
||||
layout_manager_class->allocate = gtk_box_layout_allocate;
|
||||
|
||||
|
||||
@@ -2061,6 +2061,22 @@ gtk_builder_value_from_string_type (GtkBuilder *builder,
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GSK_TYPE_TRANSFORM))
|
||||
{
|
||||
GskTransform *transform;
|
||||
|
||||
if (gsk_transform_parse (string, &transform))
|
||||
g_value_take_boxed (value, transform);
|
||||
else
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_VALUE,
|
||||
"Could not parse transform '%s'",
|
||||
string);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
|
||||
{
|
||||
gchar **vector = g_strsplit (string, "\n", 0);
|
||||
|
||||
@@ -391,6 +391,7 @@ create_icon_helper (
|
||||
|
||||
icon_helper = gtk_icon_helper_new (gtk_style_context_get_node (gtk_widget_get_style_context (widget)),
|
||||
widget);
|
||||
_gtk_icon_helper_set_use_fallback (icon_helper, TRUE);
|
||||
_gtk_icon_helper_set_force_scale_pixbuf (icon_helper, TRUE);
|
||||
_gtk_icon_helper_set_definition (icon_helper, priv->image_def);
|
||||
|
||||
|
||||
+11
-2
@@ -835,14 +835,23 @@ gtk_compose_table_list_add_array (GSList *compose_tables,
|
||||
{
|
||||
guint32 hash;
|
||||
GtkComposeTable *compose_table;
|
||||
int n_index_stride = max_seq_len + 2;
|
||||
int length = n_index_stride * n_seqs;
|
||||
gsize n_index_stride;
|
||||
gsize length;
|
||||
gsize max_size = (gsize) -1;
|
||||
int i;
|
||||
guint16 *gtk_compose_seqs = NULL;
|
||||
|
||||
g_return_val_if_fail (data != NULL, compose_tables);
|
||||
g_return_val_if_fail (max_seq_len <= GTK_MAX_COMPOSE_LEN, compose_tables);
|
||||
|
||||
n_index_stride = MIN (max_seq_len, GTK_MAX_COMPOSE_LEN) + 2;
|
||||
if (n_seqs > max_size / n_index_stride)
|
||||
{
|
||||
g_critical ("Overflow in the compose sequences");
|
||||
return compose_tables;
|
||||
}
|
||||
|
||||
length = n_index_stride * n_seqs;
|
||||
hash = gtk_compose_table_data_hash (data, length);
|
||||
|
||||
if (g_slist_find_custom (compose_tables, GINT_TO_POINTER (hash), gtk_compose_table_find) != NULL)
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "gtkcssinheritvalueprivate.h"
|
||||
#include "gtkcssinitialvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcsssectionprivate.h"
|
||||
#include "gtkcssshorthandpropertyprivate.h"
|
||||
#include "gtkcssstaticstyleprivate.h"
|
||||
#include "gtkcssstringvalueprivate.h"
|
||||
|
||||
@@ -421,7 +421,7 @@ _gtk_css_array_value_parse (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
g_ptr_array_add (values, value);
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
result = _gtk_css_array_value_new_from_array ((GtkCssValue **) values->pdata, values->len);
|
||||
g_ptr_array_free (values, TRUE);
|
||||
|
||||
@@ -187,12 +187,12 @@ _gtk_css_bg_size_value_parse (GtkCssParser *parser)
|
||||
{
|
||||
GtkCssValue *x, *y;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "cover", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "cover"))
|
||||
return _gtk_css_value_ref (&cover_singleton);
|
||||
else if (_gtk_css_parser_try (parser, "contain", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "contain"))
|
||||
return _gtk_css_value_ref (&contain_singleton);
|
||||
|
||||
if (_gtk_css_parser_try (parser, "auto", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "auto"))
|
||||
x = NULL;
|
||||
else
|
||||
{
|
||||
@@ -204,7 +204,7 @@ _gtk_css_bg_size_value_parse (GtkCssParser *parser)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, "auto", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "auto"))
|
||||
y = NULL;
|
||||
else if (!gtk_css_number_value_can_parse (parser))
|
||||
y = NULL;
|
||||
|
||||
@@ -178,11 +178,11 @@ _gtk_css_border_value_parse (GtkCssParser *parser,
|
||||
result = _gtk_css_border_value_new (NULL, NULL, NULL, NULL);
|
||||
|
||||
if (allow_fill)
|
||||
result->fill = _gtk_css_parser_try (parser, "fill", TRUE);
|
||||
result->fill = gtk_css_parser_try_ident (parser, "fill");
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (allow_auto && _gtk_css_parser_try (parser, "auto", TRUE))
|
||||
if (allow_auto && gtk_css_parser_try_ident (parser, "auto"))
|
||||
continue;
|
||||
|
||||
if (!gtk_css_number_value_can_parse (parser))
|
||||
@@ -198,13 +198,13 @@ _gtk_css_border_value_parse (GtkCssParser *parser,
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a number");
|
||||
gtk_css_parser_error_syntax (parser, "Expected a number");
|
||||
_gtk_css_value_unref (result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (allow_fill && !result->fill)
|
||||
result->fill = _gtk_css_parser_try (parser, "fill", TRUE);
|
||||
result->fill = gtk_css_parser_try_ident (parser, "fill");
|
||||
|
||||
for (; i < 4; i++)
|
||||
{
|
||||
|
||||
+65
-38
@@ -316,25 +316,35 @@ static GtkCssValue *
|
||||
gtk_css_calc_value_parse_value (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
{
|
||||
if (_gtk_css_parser_has_prefix (parser, "calc"))
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_OPEN_PARENS))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Nested calc() expressions are not allowed.");
|
||||
return NULL;
|
||||
}
|
||||
GtkCssValue *result;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "(", TRUE))
|
||||
{
|
||||
GtkCssValue *result = gtk_css_calc_value_parse_sum (parser, flags);
|
||||
gtk_css_parser_start_block (parser);
|
||||
|
||||
result = gtk_css_calc_value_parse_sum (parser, flags);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing ')' in calc() subterm");
|
||||
_gtk_css_value_unref (result);
|
||||
gtk_css_parser_end_block (parser);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
GtkCssLocation start = *gtk_css_parser_get_start_location (parser);
|
||||
gtk_css_parser_skip_until (parser, GTK_CSS_TOKEN_EOF);
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_SYNTAX,
|
||||
&start,
|
||||
gtk_css_parser_get_start_location (parser),
|
||||
"Expected closing ')' in calc() subterm");
|
||||
gtk_css_value_unref (result);
|
||||
gtk_css_parser_end_block (parser);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_css_parser_end_block (parser);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -354,19 +364,21 @@ gtk_css_calc_value_parse_product (GtkCssParser *parser,
|
||||
{
|
||||
GtkCssValue *result, *value, *temp;
|
||||
GtkCssNumberParseFlags actual_flags;
|
||||
GtkCssLocation start;
|
||||
|
||||
actual_flags = flags | GTK_CSS_PARSE_NUMBER;
|
||||
|
||||
gtk_css_parser_get_token (parser);
|
||||
start = *gtk_css_parser_get_start_location (parser);
|
||||
result = gtk_css_calc_value_parse_value (parser, actual_flags);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
while (_gtk_css_parser_begins_with (parser, '*') || _gtk_css_parser_begins_with (parser, '/'))
|
||||
while (TRUE)
|
||||
{
|
||||
if (actual_flags != GTK_CSS_PARSE_NUMBER && !is_number (result))
|
||||
actual_flags = GTK_CSS_PARSE_NUMBER;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "*", TRUE))
|
||||
if (gtk_css_parser_try_delim (parser, '*'))
|
||||
{
|
||||
value = gtk_css_calc_value_parse_product (parser, actual_flags);
|
||||
if (value == NULL)
|
||||
@@ -379,7 +391,7 @@ gtk_css_calc_value_parse_product (GtkCssParser *parser,
|
||||
_gtk_css_value_unref (result);
|
||||
result = temp;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "/", TRUE))
|
||||
else if (gtk_css_parser_try_delim (parser, '/'))
|
||||
{
|
||||
value = gtk_css_calc_value_parse_product (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (value == NULL)
|
||||
@@ -391,14 +403,17 @@ gtk_css_calc_value_parse_product (GtkCssParser *parser,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_number (result) && !(flags & GTK_CSS_PARSE_NUMBER))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "calc() product term has no units");
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_SYNTAX,
|
||||
&start,
|
||||
gtk_css_parser_get_start_location (parser),
|
||||
"calc() product term has no units");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -419,17 +434,17 @@ gtk_css_calc_value_parse_sum (GtkCssParser *parser,
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
while (_gtk_css_parser_begins_with (parser, '+') || _gtk_css_parser_begins_with (parser, '-'))
|
||||
while (TRUE)
|
||||
{
|
||||
GtkCssValue *next, *temp;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "+", TRUE))
|
||||
if (gtk_css_parser_try_delim (parser, '+'))
|
||||
{
|
||||
next = gtk_css_calc_value_parse_product (parser, flags);
|
||||
if (next == NULL)
|
||||
goto fail;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "-", TRUE))
|
||||
else if (gtk_css_parser_try_delim (parser, '-'))
|
||||
{
|
||||
temp = gtk_css_calc_value_parse_product (parser, flags);
|
||||
if (temp == NULL)
|
||||
@@ -439,8 +454,7 @@ gtk_css_calc_value_parse_sum (GtkCssParser *parser,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
temp = gtk_css_number_value_add (result, next);
|
||||
@@ -456,32 +470,45 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkCssNumberParseFlags flags;
|
||||
GtkCssValue *value;
|
||||
} ParseCalcData;
|
||||
|
||||
static guint
|
||||
gtk_css_calc_value_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
{
|
||||
ParseCalcData *data = data_;
|
||||
|
||||
data->value = gtk_css_calc_value_parse_sum (parser, data->flags);
|
||||
if (data->value == NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_calc_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
ParseCalcData data;
|
||||
|
||||
/* This can only be handled at compute time, we allow '-' after all */
|
||||
flags &= ~GTK_CSS_POSITIVE_ONLY;
|
||||
data.flags = flags & ~GTK_CSS_POSITIVE_ONLY;
|
||||
data.value = NULL;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "calc(", TRUE))
|
||||
if (!gtk_css_parser_has_function (parser, "calc"))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected 'calc('");
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'calc('");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
value = gtk_css_calc_value_parse_sum (parser, flags);
|
||||
if (value == NULL)
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_calc_value_parse_arg, &data))
|
||||
return NULL;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_value_unref (value);
|
||||
_gtk_css_parser_error (parser, "Expected ')' after calc() statement");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return value;
|
||||
return data.value;
|
||||
}
|
||||
|
||||
|
||||
+129
-200
@@ -22,9 +22,10 @@
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkhslaprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkstylepropertyprivate.h"
|
||||
|
||||
#include "gtkprivate.h"
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
|
||||
typedef enum {
|
||||
COLOR_TYPE_LITERAL,
|
||||
@@ -510,233 +511,161 @@ _gtk_css_color_value_new_current_color (void)
|
||||
return _gtk_css_value_ref (¤t_color);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
COLOR_RGBA,
|
||||
COLOR_RGB,
|
||||
COLOR_LIGHTER,
|
||||
COLOR_DARKER,
|
||||
COLOR_SHADE,
|
||||
COLOR_ALPHA,
|
||||
COLOR_MIX
|
||||
} ColorParseType;
|
||||
|
||||
static GtkCssValue *
|
||||
_gtk_css_color_value_parse_function (GtkCssParser *parser,
|
||||
ColorParseType color)
|
||||
typedef struct
|
||||
{
|
||||
GtkCssValue *value;
|
||||
GtkCssValue *child1, *child2;
|
||||
double d;
|
||||
GtkCssValue *color;
|
||||
GtkCssValue *color2;
|
||||
double value;
|
||||
} ColorFunctionData;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing opening bracket in color definition");
|
||||
return NULL;
|
||||
}
|
||||
static guint
|
||||
parse_color_mix (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
{
|
||||
ColorFunctionData *data = data_;
|
||||
|
||||
if (color == COLOR_RGB || color == COLOR_RGBA)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
double tmp;
|
||||
guint i;
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
data->color = _gtk_css_color_value_parse (parser);
|
||||
if (data->color == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ',' in color definition");
|
||||
return NULL;
|
||||
}
|
||||
case 1:
|
||||
data->color2 = _gtk_css_color_value_parse (parser);
|
||||
if (data->color2 == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &tmp))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid number for color value");
|
||||
return NULL;
|
||||
}
|
||||
if (_gtk_css_parser_try (parser, "%", TRUE))
|
||||
tmp /= 100.0;
|
||||
else
|
||||
tmp /= 255.0;
|
||||
if (i == 0)
|
||||
rgba.red = tmp;
|
||||
else if (i == 1)
|
||||
rgba.green = tmp;
|
||||
else if (i == 2)
|
||||
rgba.blue = tmp;
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
case 2:
|
||||
if (!gtk_css_parser_consume_number (parser, &data->value))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
if (color == COLOR_RGBA)
|
||||
{
|
||||
if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ',' in color definition");
|
||||
return NULL;
|
||||
}
|
||||
default:
|
||||
g_return_val_if_reached (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &rgba.alpha))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid number for alpha value");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
rgba.alpha = 1.0;
|
||||
|
||||
value = _gtk_css_color_value_new_literal (&rgba);
|
||||
}
|
||||
else
|
||||
{
|
||||
child1 = _gtk_css_color_value_parse (parser);
|
||||
if (child1 == NULL)
|
||||
return NULL;
|
||||
static guint
|
||||
parse_color_number (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
{
|
||||
ColorFunctionData *data = data_;
|
||||
|
||||
if (color == COLOR_MIX)
|
||||
{
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ',' in color definition");
|
||||
_gtk_css_value_unref (child1);
|
||||
return NULL;
|
||||
}
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
data->color = _gtk_css_color_value_parse (parser);
|
||||
if (data->color == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
child2 = _gtk_css_color_value_parse (parser);
|
||||
if (child2 == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (child1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
child2 = NULL;
|
||||
case 1:
|
||||
if (!gtk_css_parser_consume_number (parser, &data->value))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
if (color == COLOR_LIGHTER)
|
||||
d = 1.3;
|
||||
else if (color == COLOR_DARKER)
|
||||
d = 0.7;
|
||||
else
|
||||
{
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ',' in color definition");
|
||||
_gtk_css_value_unref (child1);
|
||||
if (child2)
|
||||
_gtk_css_value_unref (child2);
|
||||
return NULL;
|
||||
}
|
||||
default:
|
||||
g_return_val_if_reached (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &d))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected number in color definition");
|
||||
_gtk_css_value_unref (child1);
|
||||
if (child2)
|
||||
_gtk_css_value_unref (child2);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (color)
|
||||
{
|
||||
case COLOR_LIGHTER:
|
||||
case COLOR_DARKER:
|
||||
case COLOR_SHADE:
|
||||
value = _gtk_css_color_value_new_shade (child1, d);
|
||||
break;
|
||||
case COLOR_ALPHA:
|
||||
value = _gtk_css_color_value_new_alpha (child1, d);
|
||||
break;
|
||||
case COLOR_MIX:
|
||||
value = _gtk_css_color_value_new_mix (child1, child2, d);
|
||||
break;
|
||||
case COLOR_RGB:
|
||||
case COLOR_RGBA:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
_gtk_css_value_unref (child1);
|
||||
if (child2)
|
||||
_gtk_css_value_unref (child2);
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ')' in color definition");
|
||||
_gtk_css_value_unref (value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return value;
|
||||
gboolean
|
||||
gtk_css_color_value_can_parse (GtkCssParser *parser)
|
||||
{
|
||||
/* This is way too generous, but meh... */
|
||||
return gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_AT_KEYWORD)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_HASH_ID)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_HASH_UNRESTRICTED)
|
||||
|| gtk_css_parser_has_function (parser, "lighter")
|
||||
|| gtk_css_parser_has_function (parser, "darker")
|
||||
|| gtk_css_parser_has_function (parser, "shade")
|
||||
|| gtk_css_parser_has_function (parser, "alpha")
|
||||
|| gtk_css_parser_has_function (parser, "mix")
|
||||
|| gtk_css_parser_has_function (parser, "rgb")
|
||||
|| gtk_css_parser_has_function (parser, "rgba");
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
{
|
||||
ColorFunctionData data = { NULL, };
|
||||
GtkCssValue *value;
|
||||
GdkRGBA rgba;
|
||||
guint color;
|
||||
const char *names[] = {"rgba", "rgb", "lighter", "darker", "shade", "alpha", "mix"};
|
||||
char *name;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "currentColor", TRUE))
|
||||
return _gtk_css_color_value_new_current_color ();
|
||||
|
||||
if (_gtk_css_parser_try (parser, "transparent", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "currentColor"))
|
||||
{
|
||||
GdkRGBA transparent = { 0, 0, 0, 0 };
|
||||
|
||||
return _gtk_css_color_value_new_literal (&transparent);
|
||||
return _gtk_css_color_value_new_current_color ();
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, "@", FALSE))
|
||||
else if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_AT_KEYWORD))
|
||||
{
|
||||
name = _gtk_css_parser_try_name (parser, TRUE);
|
||||
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (name)
|
||||
{
|
||||
value = _gtk_css_color_value_new_name (name);
|
||||
}
|
||||
value = _gtk_css_color_value_new_name (token->string.string);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
|
||||
return value;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "lighter"))
|
||||
{
|
||||
if (gtk_css_parser_consume_function (parser, 1, 1, parse_color_number, &data))
|
||||
value = _gtk_css_color_value_new_shade (data.color, 1.3);
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'%s' is not a valid color color name", name);
|
||||
value = NULL;
|
||||
}
|
||||
value = NULL;
|
||||
|
||||
g_free (name);
|
||||
g_clear_pointer (&data.color, gtk_css_value_unref);
|
||||
return value;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "darker"))
|
||||
{
|
||||
if (gtk_css_parser_consume_function (parser, 1, 1, parse_color_number, &data))
|
||||
value = _gtk_css_color_value_new_shade (data.color, 0.7);
|
||||
else
|
||||
value = NULL;
|
||||
|
||||
g_clear_pointer (&data.color, gtk_css_value_unref);
|
||||
return value;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "shade"))
|
||||
{
|
||||
if (gtk_css_parser_consume_function (parser, 2, 2, parse_color_number, &data))
|
||||
value = _gtk_css_color_value_new_shade (data.color, data.value);
|
||||
else
|
||||
value = NULL;
|
||||
|
||||
g_clear_pointer (&data.color, gtk_css_value_unref);
|
||||
return value;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "alpha"))
|
||||
{
|
||||
if (gtk_css_parser_consume_function (parser, 2, 2, parse_color_number, &data))
|
||||
value = _gtk_css_color_value_new_alpha (data.color, data.value);
|
||||
else
|
||||
value = NULL;
|
||||
|
||||
g_clear_pointer (&data.color, gtk_css_value_unref);
|
||||
return value;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "mix"))
|
||||
{
|
||||
if (gtk_css_parser_consume_function (parser, 3, 3, parse_color_mix, &data))
|
||||
value = _gtk_css_color_value_new_mix (data.color, data.color2, data.value);
|
||||
else
|
||||
value = NULL;
|
||||
|
||||
g_clear_pointer (&data.color, gtk_css_value_unref);
|
||||
g_clear_pointer (&data.color2, gtk_css_value_unref);
|
||||
return value;
|
||||
}
|
||||
|
||||
for (color = 0; color < G_N_ELEMENTS (names); color++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, names[color], TRUE))
|
||||
break;
|
||||
}
|
||||
|
||||
if (color < G_N_ELEMENTS (names))
|
||||
return _gtk_css_color_value_parse_function (parser, color);
|
||||
|
||||
if (_gtk_css_parser_try_hash_color (parser, &rgba))
|
||||
if (gdk_rgba_parser_parse (parser, &rgba))
|
||||
return _gtk_css_color_value_new_literal (&rgba);
|
||||
|
||||
name = _gtk_css_parser_try_name (parser, TRUE);
|
||||
if (name)
|
||||
{
|
||||
if (gdk_rgba_parse (&rgba, name))
|
||||
{
|
||||
value = _gtk_css_color_value_new_literal (&rgba);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'%s' is not a valid color name", name);
|
||||
value = NULL;
|
||||
}
|
||||
g_free (name);
|
||||
return value;
|
||||
}
|
||||
|
||||
_gtk_css_parser_error (parser, "Not a color definition");
|
||||
return NULL;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ GtkCssValue * _gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
gdouble factor);
|
||||
GtkCssValue * _gtk_css_color_value_new_current_color (void);
|
||||
|
||||
gboolean gtk_css_color_value_can_parse (GtkCssParser *parser);
|
||||
GtkCssValue * _gtk_css_color_value_parse (GtkCssParser *parser);
|
||||
|
||||
GtkCssValue * _gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
|
||||
@@ -325,3 +325,116 @@ gtk_css_dimension_value_new (double value,
|
||||
return result;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_dimension_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
GtkCssUnit unit;
|
||||
GtkCssNumberParseFlags required_flags;
|
||||
} units[] = {
|
||||
{ "px", GTK_CSS_PX, GTK_CSS_PARSE_LENGTH },
|
||||
{ "pt", GTK_CSS_PT, GTK_CSS_PARSE_LENGTH },
|
||||
{ "em", GTK_CSS_EM, GTK_CSS_PARSE_LENGTH },
|
||||
{ "ex", GTK_CSS_EX, GTK_CSS_PARSE_LENGTH },
|
||||
{ "rem", GTK_CSS_REM, GTK_CSS_PARSE_LENGTH },
|
||||
{ "pc", GTK_CSS_PC, GTK_CSS_PARSE_LENGTH },
|
||||
{ "in", GTK_CSS_IN, GTK_CSS_PARSE_LENGTH },
|
||||
{ "cm", GTK_CSS_CM, GTK_CSS_PARSE_LENGTH },
|
||||
{ "mm", GTK_CSS_MM, GTK_CSS_PARSE_LENGTH },
|
||||
{ "rad", GTK_CSS_RAD, GTK_CSS_PARSE_ANGLE },
|
||||
{ "deg", GTK_CSS_DEG, GTK_CSS_PARSE_ANGLE },
|
||||
{ "grad", GTK_CSS_GRAD, GTK_CSS_PARSE_ANGLE },
|
||||
{ "turn", GTK_CSS_TURN, GTK_CSS_PARSE_ANGLE },
|
||||
{ "s", GTK_CSS_S, GTK_CSS_PARSE_TIME },
|
||||
{ "ms", GTK_CSS_MS, GTK_CSS_PARSE_TIME }
|
||||
};
|
||||
const GtkCssToken *token;
|
||||
GtkCssValue *result;
|
||||
GtkCssUnit unit;
|
||||
double number;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
|
||||
/* Handle percentages first */
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_PERCENTAGE))
|
||||
{
|
||||
if (!(flags & GTK_CSS_PARSE_PERCENT))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Percentages are not allowed here");
|
||||
return NULL;
|
||||
}
|
||||
number = token->number.number;
|
||||
unit = GTK_CSS_PERCENT;
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_NUMBER) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_NUMBER))
|
||||
{
|
||||
number = token->number.number;
|
||||
if (number == 0.0)
|
||||
{
|
||||
if (flags & GTK_CSS_PARSE_NUMBER)
|
||||
unit = GTK_CSS_NUMBER;
|
||||
else if (flags & GTK_CSS_PARSE_LENGTH)
|
||||
unit = GTK_CSS_PX;
|
||||
else if (flags & GTK_CSS_PARSE_ANGLE)
|
||||
unit = GTK_CSS_DEG;
|
||||
else if (flags & GTK_CSS_PARSE_TIME)
|
||||
unit = GTK_CSS_S;
|
||||
else
|
||||
unit = GTK_CSS_PERCENT;
|
||||
}
|
||||
else if (flags & GTK_CSS_PARSE_NUMBER)
|
||||
{
|
||||
unit = GTK_CSS_NUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Unit is missing.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_DIMENSION))
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (units); i++)
|
||||
{
|
||||
if (flags & units[i].required_flags &&
|
||||
g_ascii_strcasecmp (token->dimension.dimension, units[i].name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= G_N_ELEMENTS (units))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "'%s' is not a valid unit.", token->dimension.dimension);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unit = units[i].unit;
|
||||
number = token->dimension.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a number");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & GTK_CSS_POSITIVE_ONLY &&
|
||||
number < 0)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "negative values are not allowed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = gtk_css_dimension_value_new (number, unit);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+100
-83
@@ -188,7 +188,7 @@ _gtk_css_ease_value_new_steps (guint n_steps,
|
||||
static const struct {
|
||||
const char *name;
|
||||
guint is_bezier :1;
|
||||
guint needs_custom :1;
|
||||
guint is_function :1;
|
||||
double values[4];
|
||||
} parser_values[] = {
|
||||
{ "linear", TRUE, FALSE, { 0.0, 0.0, 1.0, 1.0 } },
|
||||
@@ -209,93 +209,107 @@ _gtk_css_ease_value_can_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (parser_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_has_prefix (parser, parser_values[i].name))
|
||||
return TRUE;
|
||||
if (parser_values[i].is_function)
|
||||
{
|
||||
if (gtk_css_parser_has_function (parser, parser_values[i].name))
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_css_parser_has_ident (parser, parser_values[i].name))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_ease_value_parse_cubic_bezier_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
double *values = data;
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &values[arg]))
|
||||
return 0;
|
||||
|
||||
if (arg % 2 == 0)
|
||||
{
|
||||
if (values[arg] < 0 || values[arg] > 1.0)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "value %g out of range. Must be from 0.0 to 1.0", values[arg]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_ease_value_parse_cubic_bezier (GtkCssParser *parser)
|
||||
{
|
||||
double values[4];
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!_gtk_css_parser_try (parser, i ? "," : "(", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected '%s'", i ? "," : "(");
|
||||
return NULL;
|
||||
}
|
||||
if (!_gtk_css_parser_try_double (parser, &values[i]))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a number");
|
||||
return NULL;
|
||||
}
|
||||
if ((i == 0 || i == 2) &&
|
||||
(values[i] < 0 || values[i] > 1.0))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "value %g out of range. Must be from 0.0 to 1.0", values[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing ')' for cubic-bezier");
|
||||
return NULL;
|
||||
}
|
||||
if (!gtk_css_parser_consume_function (parser, 4, 4, gtk_css_ease_value_parse_cubic_bezier_arg, values))
|
||||
return NULL;
|
||||
|
||||
return _gtk_css_ease_value_new_cubic_bezier (values[0], values[1], values[2], values[3]);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int n_steps;
|
||||
gboolean start;
|
||||
} ParseStepsData;
|
||||
|
||||
static guint
|
||||
gtk_css_ease_value_parse_steps_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
{
|
||||
ParseStepsData *data = data_;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
if (!gtk_css_parser_consume_integer (parser, &data->n_steps))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (data->n_steps < 1)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Number of steps must be > 0");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (gtk_css_parser_try_ident (parser, "start"))
|
||||
data->start = TRUE;
|
||||
else if (gtk_css_parser_try_ident (parser, "end"))
|
||||
data->start = FALSE;
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Only allowed values are 'start' and 'end'");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (0);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_ease_value_parse_steps (GtkCssParser *parser)
|
||||
{
|
||||
int n_steps;
|
||||
gboolean start;
|
||||
ParseStepsData data = { 0, FALSE };
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected '('");
|
||||
return NULL;
|
||||
}
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 2, gtk_css_ease_value_parse_steps_arg, &data))
|
||||
return NULL;
|
||||
|
||||
if (!_gtk_css_parser_try_int (parser, &n_steps))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected number of steps");
|
||||
return NULL;
|
||||
}
|
||||
else if (n_steps < 1)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Number of steps must be > 0");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "start", TRUE))
|
||||
start = TRUE;
|
||||
else if (_gtk_css_parser_try (parser, "end", TRUE))
|
||||
start = FALSE;
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Only allowed values are 'start' and 'end'");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
start = FALSE;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing ')' for steps");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _gtk_css_ease_value_new_steps (n_steps, start);
|
||||
return _gtk_css_ease_value_new_steps (data.n_steps, data.start);
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
@@ -307,30 +321,33 @@ _gtk_css_ease_value_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (parser_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, parser_values[i].name, FALSE))
|
||||
if (parser_values[i].is_function)
|
||||
{
|
||||
if (parser_values[i].needs_custom)
|
||||
if (gtk_css_parser_has_function (parser, parser_values[i].name))
|
||||
{
|
||||
if (parser_values[i].is_bezier)
|
||||
return gtk_css_ease_value_parse_cubic_bezier (parser);
|
||||
else
|
||||
return gtk_css_ease_value_parse_steps (parser);
|
||||
}
|
||||
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
|
||||
if (parser_values[i].is_bezier)
|
||||
return _gtk_css_ease_value_new_cubic_bezier (parser_values[i].values[0],
|
||||
parser_values[i].values[1],
|
||||
parser_values[i].values[2],
|
||||
parser_values[i].values[3]);
|
||||
else
|
||||
return _gtk_css_ease_value_new_steps (parser_values[i].values[0],
|
||||
parser_values[i].values[1] != 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_css_parser_try_ident (parser, parser_values[i].name))
|
||||
{
|
||||
if (parser_values[i].is_bezier)
|
||||
return _gtk_css_ease_value_new_cubic_bezier (parser_values[i].values[0],
|
||||
parser_values[i].values[1],
|
||||
parser_values[i].values[2],
|
||||
parser_values[i].values[3]);
|
||||
else
|
||||
return _gtk_css_ease_value_new_steps (parser_values[i].values[0],
|
||||
parser_values[i].values[1] != 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_gtk_css_parser_error (parser, "Unknown value");
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid ease value");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+40
-82
@@ -117,7 +117,7 @@ _gtk_css_border_style_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (border_style_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, border_style_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, border_style_values[i].name))
|
||||
return _gtk_css_value_ref (&border_style_values[i]);
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ _gtk_css_blend_mode_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (blend_mode_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, blend_mode_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, blend_mode_values[i].name))
|
||||
return _gtk_css_value_ref (&blend_mode_values[i]);
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ _gtk_css_font_size_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_size_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_size_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_size_values[i].name))
|
||||
return _gtk_css_value_ref (&font_size_values[i]);
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ _gtk_css_font_style_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_style_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_style_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_style_values[i].name))
|
||||
return _gtk_css_value_ref (&font_style_values[i]);
|
||||
}
|
||||
|
||||
@@ -407,27 +407,27 @@ gtk_css_value_font_weight_compute (GtkCssValue *value,
|
||||
return _gtk_css_value_ref (value);
|
||||
|
||||
if (parent_style)
|
||||
parent_value = gtk_css_style_get_value (parent_style, property_id)->value;
|
||||
parent_value = _gtk_css_number_value_get (gtk_css_style_get_value (parent_style, property_id), 100);
|
||||
else
|
||||
parent_value = 400;
|
||||
|
||||
if (value->value == BOLDER)
|
||||
{
|
||||
if (parent_value < 400)
|
||||
new_weight = PANGO_WEIGHT_NORMAL;
|
||||
else if (parent_value < 600)
|
||||
new_weight = PANGO_WEIGHT_BOLD;
|
||||
if (parent_value < 350)
|
||||
new_weight = 400;
|
||||
else if (parent_value < 550)
|
||||
new_weight = 700;
|
||||
else
|
||||
new_weight = PANGO_WEIGHT_HEAVY;
|
||||
new_weight = 900;
|
||||
}
|
||||
else if (value->value == LIGHTER)
|
||||
{
|
||||
if (parent_value > 700)
|
||||
new_weight = PANGO_WEIGHT_BOLD;
|
||||
else if (parent_value > 500)
|
||||
new_weight = PANGO_WEIGHT_NORMAL;
|
||||
if (parent_value > 750)
|
||||
new_weight = 700;
|
||||
else if (parent_value > 550)
|
||||
new_weight = 400;
|
||||
else
|
||||
new_weight = PANGO_WEIGHT_THIN;
|
||||
new_weight = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -435,30 +435,14 @@ gtk_css_value_font_weight_compute (GtkCssValue *value,
|
||||
new_weight = PANGO_WEIGHT_NORMAL;
|
||||
}
|
||||
|
||||
return _gtk_css_font_weight_value_new (new_weight);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_font_weight_transition (GtkCssValue *start,
|
||||
GtkCssValue *end,
|
||||
guint property_id,
|
||||
double progress)
|
||||
{
|
||||
PangoWeight new_weight;
|
||||
|
||||
if (start->value < 0 || end->value < 0)
|
||||
return NULL;
|
||||
|
||||
new_weight = (start->value + end->value + 50) / 200 * 100;
|
||||
|
||||
return _gtk_css_font_weight_value_new (new_weight);
|
||||
return _gtk_css_number_value_new (new_weight, GTK_CSS_NUMBER);
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = {
|
||||
gtk_css_value_enum_free,
|
||||
gtk_css_value_font_weight_compute,
|
||||
gtk_css_value_enum_equal,
|
||||
gtk_css_value_font_weight_transition,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
gtk_css_value_enum_print
|
||||
@@ -467,36 +451,10 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = {
|
||||
static GtkCssValue font_weight_values[] = {
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, BOLDER, "bolder" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, LIGHTER, "lighter" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_THIN, "100" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRALIGHT, "200" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_LIGHT, "300" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_NORMAL, "normal" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_MEDIUM, "500" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_SEMIBOLD, "600" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_BOLD, "bold" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRABOLD, "800" },
|
||||
{ >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_HEAVY, "900" }
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_font_weight_value_new (PangoWeight font_weight)
|
||||
{
|
||||
guint i;
|
||||
gint w;
|
||||
|
||||
w = ((font_weight + 50) / 100) * 100;
|
||||
|
||||
for (i = 2; i < G_N_ELEMENTS (font_weight_values); i++)
|
||||
{
|
||||
if (font_weight_values[i].value == w)
|
||||
return _gtk_css_value_ref (&font_weight_values[i]);
|
||||
}
|
||||
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_font_weight_value_try_parse (GtkCssParser *parser)
|
||||
gtk_css_font_weight_value_try_parse (GtkCssParser *parser)
|
||||
{
|
||||
guint i;
|
||||
|
||||
@@ -504,20 +462,20 @@ _gtk_css_font_weight_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_weight_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_weight_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_weight_values[i].name))
|
||||
return _gtk_css_value_ref (&font_weight_values[i]);
|
||||
}
|
||||
/* special cases go here */
|
||||
if (_gtk_css_parser_try (parser, "400", TRUE))
|
||||
return _gtk_css_value_ref (&font_weight_values[5]);
|
||||
if (_gtk_css_parser_try (parser, "700", TRUE))
|
||||
return _gtk_css_value_ref (&font_weight_values[8]);
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "normal"))
|
||||
return _gtk_css_number_value_new (PANGO_WEIGHT_NORMAL, GTK_CSS_NUMBER);
|
||||
if (gtk_css_parser_try_ident (parser, "bold"))
|
||||
return _gtk_css_number_value_new (PANGO_WEIGHT_BOLD, GTK_CSS_NUMBER);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PangoWeight
|
||||
_gtk_css_font_weight_value_get (const GtkCssValue *value)
|
||||
gtk_css_font_weight_value_get (const GtkCssValue *value)
|
||||
{
|
||||
g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_WEIGHT, PANGO_WEIGHT_NORMAL);
|
||||
|
||||
@@ -568,7 +526,7 @@ _gtk_css_font_stretch_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_stretch_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_stretch_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_stretch_values[i].name))
|
||||
return _gtk_css_value_ref (&font_stretch_values[i]);
|
||||
}
|
||||
|
||||
@@ -618,7 +576,7 @@ _gtk_css_text_decoration_line_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (text_decoration_line_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, text_decoration_line_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, text_decoration_line_values[i].name))
|
||||
return _gtk_css_value_ref (&text_decoration_line_values[i]);
|
||||
}
|
||||
|
||||
@@ -668,7 +626,7 @@ _gtk_css_text_decoration_style_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (text_decoration_style_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, text_decoration_style_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, text_decoration_style_values[i].name))
|
||||
return _gtk_css_value_ref (&text_decoration_style_values[i]);
|
||||
}
|
||||
|
||||
@@ -724,7 +682,7 @@ _gtk_css_area_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (area_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, area_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, area_values[i].name))
|
||||
return _gtk_css_value_ref (&area_values[i]);
|
||||
}
|
||||
|
||||
@@ -784,7 +742,7 @@ _gtk_css_direction_value_try_parse (GtkCssParser *parser)
|
||||
*/
|
||||
for (i = G_N_ELEMENTS (direction_values) - 1; i >= 0; i--)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, direction_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, direction_values[i].name))
|
||||
return _gtk_css_value_ref (&direction_values[i]);
|
||||
}
|
||||
|
||||
@@ -839,7 +797,7 @@ _gtk_css_play_state_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (play_state_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, play_state_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, play_state_values[i].name))
|
||||
return _gtk_css_value_ref (&play_state_values[i]);
|
||||
}
|
||||
|
||||
@@ -896,7 +854,7 @@ _gtk_css_fill_mode_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (fill_mode_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, fill_mode_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, fill_mode_values[i].name))
|
||||
return _gtk_css_value_ref (&fill_mode_values[i]);
|
||||
}
|
||||
|
||||
@@ -952,7 +910,7 @@ _gtk_css_icon_style_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (icon_style_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, icon_style_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, icon_style_values[i].name))
|
||||
return _gtk_css_value_ref (&icon_style_values[i]);
|
||||
}
|
||||
|
||||
@@ -1008,7 +966,7 @@ _gtk_css_font_kerning_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_kerning_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_kerning_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_kerning_values[i].name))
|
||||
return _gtk_css_value_ref (&font_kerning_values[i]);
|
||||
}
|
||||
|
||||
@@ -1064,7 +1022,7 @@ _gtk_css_font_variant_position_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_variant_position_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_variant_position_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_variant_position_values[i].name))
|
||||
return _gtk_css_value_ref (&font_variant_position_values[i]);
|
||||
}
|
||||
|
||||
@@ -1124,7 +1082,7 @@ _gtk_css_font_variant_caps_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_variant_caps_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_variant_caps_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_variant_caps_values[i].name))
|
||||
return _gtk_css_value_ref (&font_variant_caps_values[i]);
|
||||
}
|
||||
|
||||
@@ -1179,7 +1137,7 @@ _gtk_css_font_variant_alternate_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_variant_alternate_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_variant_alternate_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_variant_alternate_values[i].name))
|
||||
return _gtk_css_value_ref (&font_variant_alternate_values[i]);
|
||||
}
|
||||
|
||||
@@ -1310,7 +1268,7 @@ _gtk_css_font_variant_ligature_try_parse_one (GtkCssParser *parser,
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_variant_ligature_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_variant_ligature_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_variant_ligature_values[i].name))
|
||||
{
|
||||
value = font_variant_ligature_values[i].value;
|
||||
break;
|
||||
@@ -1412,7 +1370,7 @@ _gtk_css_font_variant_numeric_try_parse_one (GtkCssParser *parser,
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_variant_numeric_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_variant_numeric_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_variant_numeric_values[i].name))
|
||||
{
|
||||
value = font_variant_numeric_values[i].value;
|
||||
break;
|
||||
@@ -1554,7 +1512,7 @@ _gtk_css_font_variant_east_asian_try_parse_one (GtkCssParser *pars
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (font_variant_east_asian_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, font_variant_east_asian_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, font_variant_east_asian_values[i].name))
|
||||
{
|
||||
value = font_variant_east_asian_values[i].value;
|
||||
break;
|
||||
|
||||
@@ -45,9 +45,8 @@ GtkCssValue * _gtk_css_font_style_value_new (PangoStyle style)
|
||||
GtkCssValue * _gtk_css_font_style_value_try_parse (GtkCssParser *parser);
|
||||
PangoStyle _gtk_css_font_style_value_get (const GtkCssValue *value);
|
||||
|
||||
GtkCssValue * _gtk_css_font_weight_value_new (PangoWeight weight);
|
||||
GtkCssValue * _gtk_css_font_weight_value_try_parse (GtkCssParser *parser);
|
||||
PangoWeight _gtk_css_font_weight_value_get (const GtkCssValue *value);
|
||||
GtkCssValue * gtk_css_font_weight_value_try_parse (GtkCssParser *parser);
|
||||
PangoWeight gtk_css_font_weight_value_get (const GtkCssValue *value);
|
||||
|
||||
GtkCssValue * _gtk_css_font_stretch_value_new (PangoStretch stretch);
|
||||
GtkCssValue * _gtk_css_font_stretch_value_try_parse (GtkCssParser *parser);
|
||||
|
||||
+119
-95
@@ -729,96 +729,46 @@ gtk_css_filter_value_is_none (const GtkCssValue *value)
|
||||
return value->n_filters == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_filter_parse (GtkCssFilter *filter,
|
||||
GtkCssParser *parser)
|
||||
static guint
|
||||
gtk_css_filter_parse_number (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "brightness(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_BRIGHTNESS;
|
||||
GtkCssValue **values = data;
|
||||
|
||||
filter->brightness.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT);
|
||||
if (filter->brightness.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "contrast(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_CONTRAST;
|
||||
values[n] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT);
|
||||
if (values[n] == NULL)
|
||||
return 0;
|
||||
|
||||
filter->contrast.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT);
|
||||
if (filter->contrast.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "grayscale(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_GRAYSCALE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
filter->grayscale.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT);
|
||||
if (filter->grayscale.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "hue-rotate(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_HUE_ROTATE;
|
||||
static guint
|
||||
gtk_css_filter_parse_length (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssValue **values = data;
|
||||
|
||||
filter->hue_rotate.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (filter->hue_rotate.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "invert(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_INVERT;
|
||||
values[n] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (values[n] == NULL)
|
||||
return 0;
|
||||
|
||||
filter->invert.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT);
|
||||
if (filter->invert.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "opacity(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_OPACITY;
|
||||
return 1;
|
||||
}
|
||||
|
||||
filter->opacity.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT);
|
||||
if (filter->opacity.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "saturate(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_SATURATE;
|
||||
static guint
|
||||
gtk_css_filter_parse_angle (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssValue **values = data;
|
||||
|
||||
filter->saturate.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT);
|
||||
if (filter->saturate.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "sepia(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_SEPIA;
|
||||
values[n] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (values[n] == NULL)
|
||||
return 0;
|
||||
|
||||
filter->sepia.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT);
|
||||
if (filter->sepia.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "blur(", TRUE))
|
||||
{
|
||||
filter->type = GTK_CSS_FILTER_BLUR;
|
||||
|
||||
filter->blur.value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (filter->blur.value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "unknown syntax for filter");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
gtk_css_filter_clear (filter);
|
||||
_gtk_css_parser_error (parser, "Expected closing ')'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
@@ -828,25 +778,91 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
GArray *array;
|
||||
guint i;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "none", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
return gtk_css_filter_value_new_none ();
|
||||
|
||||
array = g_array_new (FALSE, FALSE, sizeof (GtkCssFilter));
|
||||
|
||||
do {
|
||||
GtkCssFilter filter;
|
||||
while (TRUE)
|
||||
{
|
||||
GtkCssFilter filter;
|
||||
|
||||
if (!gtk_css_filter_parse (&filter, parser))
|
||||
{
|
||||
for (i = 0; i < array->len; i++)
|
||||
{
|
||||
gtk_css_filter_clear (&g_array_index (array, GtkCssFilter, i));
|
||||
}
|
||||
g_array_free (array, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
g_array_append_val (array, filter);
|
||||
} while (!_gtk_css_parser_begins_with (parser, ';'));
|
||||
if (gtk_css_parser_has_function (parser, "blur"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_length, &filter.blur.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_BLUR;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "brightness"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_number, &filter.brightness.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_BRIGHTNESS;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "contrast"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_number, &filter.contrast.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_CONTRAST;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "grayscale"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_number, &filter.grayscale.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_GRAYSCALE;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "hue-rotate"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_angle, &filter.blur.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_HUE_ROTATE;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "invert"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_number, &filter.invert.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_INVERT;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "opacity"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_number, &filter.opacity.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_OPACITY;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "saturate"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_number, &filter.saturate.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_SATURATE;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "sepia"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_number, &filter.sepia.value))
|
||||
goto fail;
|
||||
|
||||
filter.type = GTK_CSS_FILTER_SEPIA;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
g_array_append_val (array, filter);
|
||||
}
|
||||
|
||||
if (array->len == 0)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a filter");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
value = gtk_css_filter_value_alloc (array->len);
|
||||
memcpy (value->filters, array->data, sizeof (GtkCssFilter) * array->len);
|
||||
@@ -854,6 +870,14 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
|
||||
g_array_free (array, TRUE);
|
||||
|
||||
return value;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < array->len; i++)
|
||||
{
|
||||
gtk_css_filter_clear (&g_array_index (array, GtkCssFilter, i));
|
||||
}
|
||||
g_array_free (array, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -230,14 +230,13 @@ gtk_css_font_features_value_parse (GtkCssParser *parser)
|
||||
char *name;
|
||||
int num;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "normal", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "normal"))
|
||||
return gtk_css_font_features_value_new_default ();
|
||||
|
||||
result = gtk_css_font_features_value_new_empty ();
|
||||
|
||||
do {
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
name = _gtk_css_parser_read_string (parser);
|
||||
name = gtk_css_parser_consume_string (parser);
|
||||
if (name == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (result);
|
||||
@@ -246,24 +245,35 @@ gtk_css_font_features_value_parse (GtkCssParser *parser)
|
||||
|
||||
if (!is_valid_opentype_tag (name))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid OpenType tag.");
|
||||
gtk_css_parser_error_value (parser, "Not a valid OpenType tag.");
|
||||
g_free (name);
|
||||
_gtk_css_value_unref (result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, "on", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "on"))
|
||||
val = _gtk_css_number_value_new (1.0, GTK_CSS_NUMBER);
|
||||
else if (_gtk_css_parser_try (parser, "off", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "off"))
|
||||
val = _gtk_css_number_value_new (0.0, GTK_CSS_NUMBER);
|
||||
else if (_gtk_css_parser_try_int (parser, &num))
|
||||
val = _gtk_css_number_value_new ((double)num, GTK_CSS_NUMBER);
|
||||
else if (gtk_css_parser_has_integer (parser))
|
||||
{
|
||||
if (gtk_css_parser_consume_integer (parser, &num))
|
||||
{
|
||||
val = _gtk_css_number_value_new ((double)num, GTK_CSS_NUMBER);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (name);
|
||||
_gtk_css_value_unref (result);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
val = _gtk_css_number_value_new (1.0, GTK_CSS_NUMBER);
|
||||
|
||||
gtk_css_font_features_value_add_feature (result, name, val);
|
||||
g_free (name);
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -228,14 +228,13 @@ gtk_css_font_variations_value_parse (GtkCssParser *parser)
|
||||
GtkCssValue *result, *coord;
|
||||
char *name;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "normal", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "normal"))
|
||||
return gtk_css_font_variations_value_new_default ();
|
||||
|
||||
result = gtk_css_font_variations_value_new_empty ();
|
||||
|
||||
do {
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
name = _gtk_css_parser_read_string (parser);
|
||||
name = gtk_css_parser_consume_string (parser);
|
||||
if (name == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (result);
|
||||
@@ -244,7 +243,7 @@ gtk_css_font_variations_value_parse (GtkCssParser *parser)
|
||||
|
||||
if (!is_valid_opentype_tag (name))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid OpenType tag.");
|
||||
gtk_css_parser_error_value (parser, "Not a valid OpenType tag.");
|
||||
g_free (name);
|
||||
_gtk_css_value_unref (result);
|
||||
return NULL;
|
||||
@@ -260,7 +259,7 @@ gtk_css_font_variations_value_parse (GtkCssParser *parser)
|
||||
|
||||
gtk_css_font_variations_value_add_axis (result, name, coord);
|
||||
g_free (name);
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ gtk_css_icon_theme_value_parse (GtkCssParser *parser)
|
||||
GtkCssValue *result;
|
||||
char *s;
|
||||
|
||||
s = _gtk_css_parser_read_string (parser);
|
||||
s = gtk_css_parser_consume_string (parser);
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
+6
-3
@@ -502,17 +502,20 @@ gtk_css_image_get_parser_type (GtkCssParser *parser)
|
||||
{ "repeating-linear-gradient", _gtk_css_image_linear_get_type },
|
||||
{ "radial-gradient", _gtk_css_image_radial_get_type },
|
||||
{ "repeating-radial-gradient", _gtk_css_image_radial_get_type },
|
||||
{ "cross-fade", _gtk_css_image_cross_fade_get_type },
|
||||
{ "cross-fade", gtk_css_image_cross_fade_get_type },
|
||||
{ "image", _gtk_css_image_fallback_get_type }
|
||||
};
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (image_types); i++)
|
||||
{
|
||||
if (_gtk_css_parser_has_prefix (parser, image_types[i].prefix))
|
||||
if (gtk_css_parser_has_function (parser, image_types[i].prefix))
|
||||
return image_types[i].type_func ();
|
||||
}
|
||||
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_URL))
|
||||
return _gtk_css_image_url_get_type ();
|
||||
|
||||
return G_TYPE_INVALID;
|
||||
}
|
||||
|
||||
@@ -545,7 +548,7 @@ _gtk_css_image_new_parse (GtkCssParser *parser)
|
||||
image_type = gtk_css_image_get_parser_type (parser);
|
||||
if (image_type == G_TYPE_INVALID)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid image");
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid image");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -457,9 +457,9 @@ static gboolean
|
||||
gtk_css_image_builtin_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
if (!_gtk_css_parser_try (parser, "builtin", TRUE))
|
||||
if (!gtk_css_parser_try_ident (parser, "builtin"))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected 'builtin'");
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'builtin'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
+299
-150
@@ -26,64 +26,149 @@
|
||||
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageCrossFade, _gtk_css_image_cross_fade, GTK_TYPE_CSS_IMAGE)
|
||||
typedef struct _CrossFadeEntry CrossFadeEntry;
|
||||
|
||||
struct _CrossFadeEntry
|
||||
{
|
||||
double progress;
|
||||
gboolean has_progress;
|
||||
GtkCssImage *image;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageCrossFade, gtk_css_image_cross_fade, GTK_TYPE_CSS_IMAGE)
|
||||
|
||||
static void
|
||||
cross_fade_entry_clear (gpointer data)
|
||||
{
|
||||
CrossFadeEntry *entry = data;
|
||||
|
||||
g_clear_object (&entry->image);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_cross_fade_recalculate_progress (GtkCssImageCrossFade *self)
|
||||
{
|
||||
double total_progress;
|
||||
guint n_no_progress;
|
||||
guint i;
|
||||
|
||||
total_progress = 0.0;
|
||||
n_no_progress = 0;
|
||||
|
||||
for (i = 0; i < self->images->len; i++)
|
||||
{
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
|
||||
if (entry->has_progress)
|
||||
total_progress += entry->progress;
|
||||
else
|
||||
n_no_progress++;
|
||||
}
|
||||
|
||||
if (n_no_progress)
|
||||
{
|
||||
double progress;
|
||||
if (total_progress >= 1.0)
|
||||
{
|
||||
progress = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
progress = (1.0 - total_progress) / n_no_progress;
|
||||
total_progress = 1.0;
|
||||
}
|
||||
for (i = 0; i < self->images->len; i++)
|
||||
{
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
|
||||
if (!entry->has_progress)
|
||||
entry->progress = progress;
|
||||
}
|
||||
}
|
||||
|
||||
self->total_progress = total_progress;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_cross_fade_add (GtkCssImageCrossFade *self,
|
||||
gboolean has_progress,
|
||||
double progress,
|
||||
GtkCssImage *image)
|
||||
{
|
||||
CrossFadeEntry entry;
|
||||
|
||||
entry.has_progress = has_progress;
|
||||
entry.progress = progress;
|
||||
entry.image = image;
|
||||
g_array_append_val (self->images, entry);
|
||||
|
||||
gtk_css_image_cross_fade_recalculate_progress (self);
|
||||
}
|
||||
|
||||
static GtkCssImageCrossFade *
|
||||
gtk_css_image_cross_fade_new_empty (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_CSS_IMAGE_CROSS_FADE, NULL);
|
||||
}
|
||||
|
||||
/* XXX: The following is not correct, it should actually run the
|
||||
* CSS sizing algorithm for every child, not just query height and
|
||||
* width independently.
|
||||
*/
|
||||
static int
|
||||
gtk_css_image_cross_fade_get_width (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
int start_width, end_width;
|
||||
GtkCssImageCrossFade *self = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
double sum_width, sum_progress;
|
||||
guint i;
|
||||
|
||||
if (cross_fade->start)
|
||||
sum_width = 0.0;
|
||||
sum_progress = 0.0;
|
||||
|
||||
for (i = 0; i < self->images->len; i++)
|
||||
{
|
||||
start_width = _gtk_css_image_get_width (cross_fade->start);
|
||||
/* no intrinsic width, what now? */
|
||||
if (start_width == 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
start_width = 0;
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
int image_width;
|
||||
|
||||
if (cross_fade->end)
|
||||
{
|
||||
end_width = _gtk_css_image_get_width (cross_fade->end);
|
||||
/* no intrinsic width, what now? */
|
||||
if (end_width == 0)
|
||||
return 0;
|
||||
image_width = _gtk_css_image_get_width (entry->image);
|
||||
if (image_width == 0)
|
||||
continue;
|
||||
sum_width += image_width * entry->progress;
|
||||
sum_progress += entry->progress;
|
||||
}
|
||||
else
|
||||
end_width = 0;
|
||||
|
||||
return start_width + (end_width - start_width) * cross_fade->progress;
|
||||
if (sum_progress <= 0.0)
|
||||
return 0;
|
||||
|
||||
return ceil (sum_width / sum_progress);
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_css_image_cross_fade_get_height (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
int start_height, end_height;
|
||||
GtkCssImageCrossFade *self = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
double sum_height, sum_progress;
|
||||
guint i;
|
||||
|
||||
if (cross_fade->start)
|
||||
sum_height = 0.0;
|
||||
sum_progress = 0.0;
|
||||
|
||||
for (i = 0; i < self->images->len; i++)
|
||||
{
|
||||
start_height = _gtk_css_image_get_height (cross_fade->start);
|
||||
/* no intrinsic height, what now? */
|
||||
if (start_height == 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
start_height = 0;
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
int image_height;
|
||||
|
||||
if (cross_fade->end)
|
||||
{
|
||||
end_height = _gtk_css_image_get_height (cross_fade->end);
|
||||
/* no intrinsic height, what now? */
|
||||
if (end_height == 0)
|
||||
return 0;
|
||||
image_height = _gtk_css_image_get_height (entry->image);
|
||||
if (image_height == 0)
|
||||
continue;
|
||||
sum_height += image_height * entry->progress;
|
||||
sum_progress += entry->progress;
|
||||
}
|
||||
else
|
||||
end_height = 0;
|
||||
|
||||
return start_height + (end_height - start_height) * cross_fade->progress;
|
||||
if (sum_progress <= 0.0)
|
||||
return 0;
|
||||
|
||||
return ceil (sum_height / sum_progress);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -92,45 +177,62 @@ gtk_css_image_cross_fade_equal (GtkCssImage *image1,
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade1 = GTK_CSS_IMAGE_CROSS_FADE (image1);
|
||||
GtkCssImageCrossFade *cross_fade2 = GTK_CSS_IMAGE_CROSS_FADE (image2);
|
||||
guint i;
|
||||
|
||||
return cross_fade1->progress == cross_fade2->progress &&
|
||||
_gtk_css_image_equal (cross_fade1->start, cross_fade2->start) &&
|
||||
_gtk_css_image_equal (cross_fade1->end, cross_fade2->end);
|
||||
if (cross_fade1->images->len != cross_fade2->images->len)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < cross_fade1->images->len; i++)
|
||||
{
|
||||
CrossFadeEntry *entry1 = &g_array_index (cross_fade1->images, CrossFadeEntry, i);
|
||||
CrossFadeEntry *entry2 = &g_array_index (cross_fade2->images, CrossFadeEntry, i);
|
||||
|
||||
if (entry1->progress != entry2->progress ||
|
||||
!_gtk_css_image_equal (entry1->image, entry2->image))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_cross_fade_is_dynamic (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
GtkCssImageCrossFade *self = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
guint i;
|
||||
|
||||
return (cross_fade->start && gtk_css_image_is_dynamic (cross_fade->start))
|
||||
|| (cross_fade->end && gtk_css_image_is_dynamic (cross_fade->end));
|
||||
for (i = 0; i < self->images->len; i++)
|
||||
{
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
|
||||
if (gtk_css_image_is_dynamic (entry->image))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkCssImage *
|
||||
gtk_css_image_cross_fade_get_dynamic_image (GtkCssImage *image,
|
||||
gint64 monotonic_time)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
GtkCssImage *start, *end, *result;
|
||||
GtkCssImageCrossFade *self = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
GtkCssImageCrossFade *result;
|
||||
guint i;
|
||||
|
||||
if (cross_fade->start)
|
||||
start = gtk_css_image_get_dynamic_image (cross_fade->start, monotonic_time);
|
||||
else
|
||||
start = NULL;
|
||||
if (cross_fade->end)
|
||||
end = gtk_css_image_get_dynamic_image (cross_fade->end, monotonic_time);
|
||||
else
|
||||
end = NULL;
|
||||
result = gtk_css_image_cross_fade_new_empty ();
|
||||
|
||||
result = _gtk_css_image_cross_fade_new (start, end, cross_fade->progress);
|
||||
for (i = 0; i < self->images->len; i++)
|
||||
{
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
|
||||
if (start)
|
||||
g_object_unref (start);
|
||||
if (end)
|
||||
g_object_unref (end);
|
||||
gtk_css_image_cross_fade_add (result,
|
||||
entry->has_progress,
|
||||
entry->progress,
|
||||
gtk_css_image_get_dynamic_image (entry->image, monotonic_time));
|
||||
}
|
||||
|
||||
return result;
|
||||
return GTK_CSS_IMAGE (result);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -139,91 +241,140 @@ gtk_css_image_cross_fade_snapshot (GtkCssImage *image,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
GtkCssImageCrossFade *self = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
double remaining;
|
||||
guint i, n_cross_fades;
|
||||
|
||||
gtk_snapshot_push_cross_fade (snapshot, cross_fade->progress);
|
||||
if (self->total_progress < 1.0)
|
||||
{
|
||||
n_cross_fades = self->images->len;
|
||||
remaining = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
n_cross_fades = self->images->len - 1;
|
||||
remaining = self->total_progress;
|
||||
}
|
||||
|
||||
if (cross_fade->start)
|
||||
gtk_css_image_snapshot (cross_fade->start, snapshot, width, height);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
for (i = 0; i < n_cross_fades; i++)
|
||||
{
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
|
||||
if (cross_fade->end)
|
||||
gtk_css_image_snapshot (cross_fade->end, snapshot, width, height);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_push_cross_fade (snapshot, 1.0 - entry->progress / remaining);
|
||||
remaining -= entry->progress;
|
||||
gtk_css_image_snapshot (entry->image, snapshot, width, height);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
if (n_cross_fades < self->images->len)
|
||||
{
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, self->images->len - 1);
|
||||
gtk_css_image_snapshot (entry->image, snapshot, width, height);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_cross_fades; i++)
|
||||
{
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_cross_fade_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
parse_progress (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
if (!_gtk_css_parser_try (parser, "cross-fade(", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected 'cross-fade('");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
GtkCssValue *number;
|
||||
|
||||
number = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_PERCENT | GTK_CSS_POSITIVE_ONLY);
|
||||
if (number == NULL)
|
||||
return FALSE;
|
||||
cross_fade->progress = _gtk_css_number_value_get (number, 1);
|
||||
_gtk_css_value_unref (number);
|
||||
|
||||
if (cross_fade->progress > 1.0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Percentages over 100%% are not allowed");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
cross_fade->progress = 0.5;
|
||||
|
||||
cross_fade->end = _gtk_css_image_new_parse (parser);
|
||||
if (cross_fade->end == NULL)
|
||||
double *progress = option_data;
|
||||
GtkCssValue *number;
|
||||
|
||||
number = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_PERCENT | GTK_CSS_POSITIVE_ONLY);
|
||||
if (number == NULL)
|
||||
return FALSE;
|
||||
*progress = _gtk_css_number_value_get (number, 1);
|
||||
_gtk_css_value_unref (number);
|
||||
|
||||
if (_gtk_css_parser_try (parser, ",", TRUE))
|
||||
if (*progress > 1.0)
|
||||
{
|
||||
/* XXX: allow parsing colors here */
|
||||
cross_fade->start = _gtk_css_image_new_parse (parser);
|
||||
if (cross_fade->start == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing bracket");
|
||||
gtk_css_parser_error_value (parser, "Percentages over 100%% are not allowed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_image (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssImage **image = option_data;
|
||||
|
||||
*image = _gtk_css_image_new_parse (parser);
|
||||
if (*image == NULL)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_cross_fade_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssImageCrossFade *self = data;
|
||||
double progress = -1.0;
|
||||
GtkCssImage *image = NULL;
|
||||
GtkCssParseOption options[] =
|
||||
{
|
||||
{ (void *) gtk_css_number_value_can_parse, parse_progress, &progress },
|
||||
{ NULL, parse_image, &image },
|
||||
};
|
||||
|
||||
if (!gtk_css_parser_consume_any (parser, options, G_N_ELEMENTS (options), self))
|
||||
return 0;
|
||||
|
||||
g_assert (image != NULL);
|
||||
|
||||
if (progress < 0.0)
|
||||
gtk_css_image_cross_fade_add (self, FALSE, 0.0, image);
|
||||
else
|
||||
gtk_css_image_cross_fade_add (self, TRUE, progress, image);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_cross_fade_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
if (!gtk_css_parser_has_function (parser, "cross-fade"))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'cross-fade('");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gtk_css_parser_consume_function (parser, 1, G_MAXUINT, gtk_css_image_cross_fade_parse_arg, image);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_cross_fade_print (GtkCssImage *image,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
GtkCssImageCrossFade *self = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
guint i;
|
||||
|
||||
g_string_append (string, "cross-fade(");
|
||||
if (cross_fade->progress != 0.5)
|
||||
|
||||
for (i = 0; i < self->images->len; i++)
|
||||
{
|
||||
g_string_append_printf (string, "%g%% ", cross_fade->progress * 100.0);
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
|
||||
if (i > 0)
|
||||
g_string_append_printf (string, ", ");
|
||||
if (entry->has_progress)
|
||||
g_string_append_printf (string, "%g%% ", entry->progress * 100.0);
|
||||
_gtk_css_image_print (entry->image, string);
|
||||
}
|
||||
|
||||
if (cross_fade->end)
|
||||
_gtk_css_image_print (cross_fade->end, string);
|
||||
else
|
||||
g_string_append (string, "none");
|
||||
if (cross_fade->start)
|
||||
{
|
||||
g_string_append (string, ", ");
|
||||
_gtk_css_image_print (cross_fade->start, string);
|
||||
}
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
|
||||
@@ -234,26 +385,23 @@ gtk_css_image_cross_fade_compute (GtkCssImage *image,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
GtkCssImage *start, *end, *computed;
|
||||
GtkCssImageCrossFade *self = GTK_CSS_IMAGE_CROSS_FADE (image);
|
||||
GtkCssImageCrossFade *result;
|
||||
guint i;
|
||||
|
||||
if (cross_fade->start)
|
||||
start = _gtk_css_image_compute (cross_fade->start, property_id, provider, style, parent_style);
|
||||
else
|
||||
start = NULL;
|
||||
if (cross_fade->end)
|
||||
end = _gtk_css_image_compute (cross_fade->end, property_id, provider, style, parent_style);
|
||||
else
|
||||
end = NULL;
|
||||
result = gtk_css_image_cross_fade_new_empty ();
|
||||
|
||||
computed = _gtk_css_image_cross_fade_new (start, end, cross_fade->progress);
|
||||
for (i = 0; i < self->images->len; i++)
|
||||
{
|
||||
CrossFadeEntry *entry = &g_array_index (self->images, CrossFadeEntry, i);
|
||||
|
||||
if (start)
|
||||
g_object_unref (start);
|
||||
if (end)
|
||||
g_object_unref (end);
|
||||
gtk_css_image_cross_fade_add (result,
|
||||
entry->has_progress,
|
||||
entry->progress,
|
||||
_gtk_css_image_compute (entry->image, property_id, provider, style, parent_style));
|
||||
}
|
||||
|
||||
return computed;
|
||||
return GTK_CSS_IMAGE (result);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -261,14 +409,13 @@ gtk_css_image_cross_fade_dispose (GObject *object)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (object);
|
||||
|
||||
g_clear_object (&cross_fade->start);
|
||||
g_clear_object (&cross_fade->end);
|
||||
g_clear_pointer (&cross_fade->images, g_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (_gtk_css_image_cross_fade_parent_class)->dispose (object);
|
||||
G_OBJECT_CLASS (gtk_css_image_cross_fade_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_cross_fade_class_init (GtkCssImageCrossFadeClass *klass)
|
||||
gtk_css_image_cross_fade_class_init (GtkCssImageCrossFadeClass *klass)
|
||||
{
|
||||
GtkCssImageClass *image_class = GTK_CSS_IMAGE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
@@ -287,8 +434,10 @@ _gtk_css_image_cross_fade_class_init (GtkCssImageCrossFadeClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_cross_fade_init (GtkCssImageCrossFade *image_cross_fade)
|
||||
gtk_css_image_cross_fade_init (GtkCssImageCrossFade *self)
|
||||
{
|
||||
self->images = g_array_new (FALSE, FALSE, sizeof (CrossFadeEntry));
|
||||
g_array_set_clear_func (self->images, cross_fade_entry_clear);
|
||||
}
|
||||
|
||||
GtkCssImage *
|
||||
@@ -296,18 +445,18 @@ _gtk_css_image_cross_fade_new (GtkCssImage *start,
|
||||
GtkCssImage *end,
|
||||
double progress)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade;
|
||||
GtkCssImageCrossFade *self;
|
||||
|
||||
g_return_val_if_fail (start == NULL || GTK_IS_CSS_IMAGE (start), NULL);
|
||||
g_return_val_if_fail (end == NULL || GTK_IS_CSS_IMAGE (end), NULL);
|
||||
|
||||
cross_fade = g_object_new (GTK_TYPE_CSS_IMAGE_CROSS_FADE, NULL);
|
||||
if (start)
|
||||
cross_fade->start = g_object_ref (start);
|
||||
if (end)
|
||||
cross_fade->end = g_object_ref (end);
|
||||
cross_fade->progress = progress;
|
||||
self = gtk_css_image_cross_fade_new_empty ();
|
||||
|
||||
return GTK_CSS_IMAGE (cross_fade);
|
||||
if (start)
|
||||
gtk_css_image_cross_fade_add (self, TRUE, 1.0 - progress, g_object_ref (start));
|
||||
if (end)
|
||||
gtk_css_image_cross_fade_add (self, TRUE, progress, g_object_ref (end));
|
||||
|
||||
return GTK_CSS_IMAGE (self);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_IMAGE_CROSS_FADE (_gtk_css_image_cross_fade_get_type ())
|
||||
#define GTK_TYPE_CSS_IMAGE_CROSS_FADE (gtk_css_image_cross_fade_get_type ())
|
||||
#define GTK_CSS_IMAGE_CROSS_FADE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_IMAGE_CROSS_FADE, GtkCssImageCrossFade))
|
||||
#define GTK_CSS_IMAGE_CROSS_FADE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_IMAGE_CROSS_FADE, GtkCssImageCrossFadeClass))
|
||||
#define GTK_IS_CSS_IMAGE_CROSS_FADE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_IMAGE_CROSS_FADE))
|
||||
@@ -38,9 +38,8 @@ struct _GtkCssImageCrossFade
|
||||
{
|
||||
GtkCssImage parent;
|
||||
|
||||
GtkCssImage *start;
|
||||
GtkCssImage *end;
|
||||
double progress;
|
||||
GArray *images;
|
||||
double total_progress;
|
||||
};
|
||||
|
||||
struct _GtkCssImageCrossFadeClass
|
||||
@@ -48,7 +47,7 @@ struct _GtkCssImageCrossFadeClass
|
||||
GtkCssImageClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_css_image_cross_fade_get_type (void) G_GNUC_CONST;
|
||||
GType gtk_css_image_cross_fade_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssImage * _gtk_css_image_cross_fade_new (GtkCssImage *start,
|
||||
GtkCssImage *end,
|
||||
|
||||
+49
-38
@@ -175,57 +175,68 @@ gtk_css_image_fallback_compute (GtkCssImage *image,
|
||||
return GTK_CSS_IMAGE (g_object_ref (fallback));
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkCssValue *color;
|
||||
GPtrArray *images;
|
||||
} ParseData;
|
||||
|
||||
static guint
|
||||
gtk_css_image_fallback_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer _data)
|
||||
{
|
||||
ParseData *data = _data;
|
||||
|
||||
if (data->color != NULL)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "The color must be the last parameter");
|
||||
return 0;
|
||||
}
|
||||
else if (_gtk_css_image_can_parse (parser))
|
||||
{
|
||||
GtkCssImage *image = _gtk_css_image_new_parse (parser);
|
||||
if (image == NULL)
|
||||
return 0;
|
||||
|
||||
g_ptr_array_add (data->images, image);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->color = _gtk_css_color_value_parse (parser);
|
||||
if (data->color == NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_fallback_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageFallback *fallback = GTK_CSS_IMAGE_FALLBACK (image);
|
||||
GPtrArray *images;
|
||||
GtkCssImage *child;
|
||||
GtkCssImageFallback *self = GTK_CSS_IMAGE_FALLBACK (image);
|
||||
ParseData data = { NULL, NULL };
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "image", TRUE))
|
||||
if (!gtk_css_parser_has_function (parser, "image"))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'image'");
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'image('");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
data.images = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, G_MAXUINT, gtk_css_image_fallback_parse_arg, &data))
|
||||
{
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected '(' after 'image'");
|
||||
g_clear_pointer (&data.color, _gtk_css_value_unref);
|
||||
g_ptr_array_free (data.images, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
images = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
do
|
||||
{
|
||||
child = NULL;
|
||||
if (_gtk_css_image_can_parse (parser))
|
||||
child = _gtk_css_image_new_parse (parser);
|
||||
if (child == NULL)
|
||||
{
|
||||
fallback->color = _gtk_css_color_value_parse (parser);
|
||||
if (fallback->color)
|
||||
break;
|
||||
|
||||
g_ptr_array_free (images, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
g_ptr_array_add (images, child);
|
||||
}
|
||||
while ( _gtk_css_parser_try (parser, ",", TRUE));
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
g_ptr_array_free (images, TRUE);
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected ')' at end of 'image'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fallback->n_images = images->len;
|
||||
fallback->images = (GtkCssImage **) g_ptr_array_free (images, FALSE);
|
||||
self->color = data.color;
|
||||
self->n_images = data.images->len;
|
||||
self->images = (GtkCssImage **) g_ptr_array_free (data.images, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+16
-15
@@ -126,30 +126,31 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_icon_theme_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssImageIconTheme *icon_theme = data;
|
||||
|
||||
icon_theme->name = gtk_css_parser_consume_string (parser);
|
||||
if (icon_theme->name == NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_icon_theme_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageIconTheme *icon_theme = GTK_CSS_IMAGE_ICON_THEME (image);
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "-gtk-icontheme(", TRUE))
|
||||
if (!gtk_css_parser_has_function (parser, "-gtk-icontheme"))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected '-gtk-icontheme('");
|
||||
gtk_css_parser_error_syntax (parser, "Expected '-gtk-icontheme('");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
icon_theme->name = _gtk_css_parser_read_string (parser);
|
||||
if (icon_theme->name == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing bracket at end of '-gtk-icontheme'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return gtk_css_parser_consume_function (parser, 1, 1, gtk_css_image_icon_theme_parse_arg, image);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+86
-78
@@ -254,61 +254,80 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_linear_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
static guint
|
||||
gtk_css_image_linear_parse_color_stop (GtkCssImageLinear *self,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
|
||||
guint i;
|
||||
GtkCssImageLinearColorStop stop;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "repeating-linear-gradient(", TRUE))
|
||||
linear->repeating = TRUE;
|
||||
else if (_gtk_css_parser_try (parser, "linear-gradient(", TRUE))
|
||||
linear->repeating = FALSE;
|
||||
stop.color = _gtk_css_color_value_parse (parser);
|
||||
if (stop.color == NULL)
|
||||
return 0;
|
||||
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
stop.offset = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_PERCENT
|
||||
| GTK_CSS_PARSE_LENGTH);
|
||||
if (stop.offset == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (stop.color);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a linear gradient");
|
||||
return FALSE;
|
||||
stop.offset = NULL;
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, "to", TRUE))
|
||||
g_array_append_val (self->stops, stop);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_linear_parse_first_arg (GtkCssImageLinear *linear,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "to"))
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "left", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "left"))
|
||||
{
|
||||
if (linear->side & ((1 << GTK_CSS_LEFT) | (1 << GTK_CSS_RIGHT)))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected 'top', 'bottom' or comma");
|
||||
return FALSE;
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'top', 'bottom' or comma");
|
||||
return 0;
|
||||
}
|
||||
linear->side |= (1 << GTK_CSS_LEFT);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "right", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "right"))
|
||||
{
|
||||
if (linear->side & ((1 << GTK_CSS_LEFT) | (1 << GTK_CSS_RIGHT)))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected 'top', 'bottom' or comma");
|
||||
return FALSE;
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'top', 'bottom' or comma");
|
||||
return 0;
|
||||
}
|
||||
linear->side |= (1 << GTK_CSS_RIGHT);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "top", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "top"))
|
||||
{
|
||||
if (linear->side & ((1 << GTK_CSS_TOP) | (1 << GTK_CSS_BOTTOM)))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected 'left', 'right' or comma");
|
||||
return FALSE;
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'left', 'right' or comma");
|
||||
return 0;
|
||||
}
|
||||
linear->side |= (1 << GTK_CSS_TOP);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "bottom", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "bottom"))
|
||||
{
|
||||
if (linear->side & ((1 << GTK_CSS_TOP) | (1 << GTK_CSS_BOTTOM)))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected 'left', 'right' or comma");
|
||||
return FALSE;
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'left', 'right' or comma");
|
||||
return 0;
|
||||
}
|
||||
linear->side |= (1 << GTK_CSS_BOTTOM);
|
||||
}
|
||||
@@ -318,72 +337,61 @@ gtk_css_image_linear_parse (GtkCssImage *image,
|
||||
|
||||
if (linear->side == 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected side that gradient should go to");
|
||||
return FALSE;
|
||||
gtk_css_parser_error_syntax (parser, "Expected side that gradient should go to");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a comma");
|
||||
return FALSE;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
linear->angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (linear->angle == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a comma");
|
||||
return FALSE;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
linear->side = 1 << GTK_CSS_BOTTOM;
|
||||
|
||||
do {
|
||||
GtkCssImageLinearColorStop stop;
|
||||
|
||||
stop.color = _gtk_css_color_value_parse (parser);
|
||||
if (stop.color == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
stop.offset = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_PERCENT
|
||||
| GTK_CSS_PARSE_LENGTH);
|
||||
if (stop.offset == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (stop.color);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stop.offset = NULL;
|
||||
}
|
||||
|
||||
g_array_append_val (linear->stops, stop);
|
||||
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
|
||||
if (linear->stops->len < 2)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "%s() needs at least 2 color stops.",
|
||||
linear->repeating ? "repeating-linear-gradient" : "linear-gradient");
|
||||
linear->side = 1 << GTK_CSS_BOTTOM;
|
||||
if (!gtk_css_image_linear_parse_color_stop (linear, parser))
|
||||
return 0;
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_linear_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssImageLinear *self = data;
|
||||
|
||||
if (arg == 0)
|
||||
return gtk_css_image_linear_parse_first_arg (self, parser);
|
||||
else
|
||||
return gtk_css_image_linear_parse_color_stop (self, parser);
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_linear_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageLinear *self = GTK_CSS_IMAGE_LINEAR (image);
|
||||
|
||||
if (gtk_css_parser_has_function (parser, "repeating-linear-gradient"))
|
||||
self->repeating = TRUE;
|
||||
else if (gtk_css_parser_has_function (parser, "linear-gradient"))
|
||||
self->repeating = FALSE;
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Not a linear gradient");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing bracket at end of linear gradient");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return gtk_css_parser_consume_function (parser, 3, G_MAXUINT, gtk_css_image_linear_parse_arg, self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+93
-74
@@ -233,11 +233,41 @@ gtk_css_image_radial_snapshot (GtkCssImage *image,
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
static guint
|
||||
gtk_css_image_radial_parse_color_stop (GtkCssImageRadial *radial,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageRadialColorStop stop;
|
||||
|
||||
stop.color = _gtk_css_color_value_parse (parser);
|
||||
if (stop.color == NULL)
|
||||
return 0;
|
||||
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
stop.offset = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_PERCENT
|
||||
| GTK_CSS_PARSE_LENGTH);
|
||||
if (stop.offset == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (stop.color);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stop.offset = NULL;
|
||||
}
|
||||
|
||||
g_array_append_val (radial->stops, stop);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_radial_parse_first_arg (GtkCssImageRadial *radial,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageRadial *radial = GTK_CSS_IMAGE_RADIAL (image);
|
||||
gboolean has_shape = FALSE;
|
||||
gboolean has_size = FALSE;
|
||||
gboolean found_one = FALSE;
|
||||
@@ -252,24 +282,15 @@ gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
{ "farthest-corner", GTK_CSS_FARTHEST_CORNER }
|
||||
};
|
||||
|
||||
if (_gtk_css_parser_try (parser, "repeating-radial-gradient(", TRUE))
|
||||
radial->repeating = TRUE;
|
||||
else if (_gtk_css_parser_try (parser, "radial-gradient(", TRUE))
|
||||
radial->repeating = FALSE;
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a radial gradient");
|
||||
return FALSE;
|
||||
}
|
||||
found_one = FALSE;
|
||||
|
||||
do {
|
||||
found_one = FALSE;
|
||||
if (!has_shape && _gtk_css_parser_try (parser, "circle", TRUE))
|
||||
if (!has_shape && gtk_css_parser_try_ident (parser, "circle"))
|
||||
{
|
||||
radial->circle = TRUE;
|
||||
found_one = has_shape = TRUE;
|
||||
}
|
||||
else if (!has_shape && _gtk_css_parser_try (parser, "ellipse", TRUE))
|
||||
else if (!has_shape && gtk_css_parser_try_ident (parser, "ellipse"))
|
||||
{
|
||||
radial->circle = FALSE;
|
||||
found_one = has_shape = TRUE;
|
||||
@@ -278,7 +299,7 @@ gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
{
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, names[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, names[i].name))
|
||||
{
|
||||
found_one = has_size = TRUE;
|
||||
radial->size = names[i].value;
|
||||
@@ -286,40 +307,39 @@ gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_size)
|
||||
if (!has_size && gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
radial->sizes[0] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH | GTK_CSS_PARSE_PERCENT);
|
||||
if (radial->sizes[0] == NULL)
|
||||
return 0;
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
radial->sizes[0] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH | GTK_CSS_PARSE_PERCENT);
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
radial->sizes[1] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH | GTK_CSS_PARSE_PERCENT);
|
||||
found_one = has_size = radial->sizes[0] != NULL;
|
||||
{
|
||||
radial->sizes[1] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH | GTK_CSS_PARSE_PERCENT);
|
||||
if (radial->sizes[1] == NULL)
|
||||
return 0;
|
||||
}
|
||||
found_one = has_size = TRUE;
|
||||
}
|
||||
if (!has_size)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (!(has_shape && has_size));
|
||||
|
||||
} while (found_one && !(has_shape && has_size));
|
||||
|
||||
if (_gtk_css_parser_try (parser, "at", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "at"))
|
||||
{
|
||||
radial->position = _gtk_css_position_value_parse (parser);
|
||||
if (!radial->position)
|
||||
return FALSE;
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a comma here");
|
||||
return FALSE;
|
||||
}
|
||||
return 0;
|
||||
found_one = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
radial->position = _gtk_css_position_value_new (_gtk_css_number_value_new (50, GTK_CSS_PERCENT),
|
||||
_gtk_css_number_value_new (50, GTK_CSS_PERCENT));
|
||||
|
||||
if ((has_shape || has_size) &&
|
||||
!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a comma here");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_size)
|
||||
@@ -339,14 +359,14 @@ gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
{
|
||||
if (radial->sizes[0] && radial->sizes[1])
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Circular gradient can only have one size");
|
||||
return FALSE;
|
||||
gtk_css_parser_error_syntax (parser, "Circular gradient can only have one size");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (radial->sizes[0] && gtk_css_number_value_has_percent (radial->sizes[0]))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Circular gradient cannot have percentage as size");
|
||||
return FALSE;
|
||||
gtk_css_parser_error_syntax (parser, "Circular gradient cannot have percentage as size");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,47 +376,46 @@ gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
radial->sizes[1] = _gtk_css_value_ref (radial->sizes[0]);
|
||||
}
|
||||
|
||||
do {
|
||||
GtkCssImageRadialColorStop stop;
|
||||
if (found_one)
|
||||
return 1;
|
||||
|
||||
stop.color = _gtk_css_color_value_parse (parser);
|
||||
if (stop.color == NULL)
|
||||
return FALSE;
|
||||
if (!gtk_css_image_radial_parse_color_stop (radial, parser))
|
||||
return 0;
|
||||
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
stop.offset = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_PERCENT
|
||||
| GTK_CSS_PARSE_LENGTH);
|
||||
if (stop.offset == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (stop.color);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stop.offset = NULL;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
g_array_append_val (radial->stops, stop);
|
||||
static guint
|
||||
gtk_css_image_radial_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssImageRadial *self = data;
|
||||
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
if (arg == 0)
|
||||
return gtk_css_image_radial_parse_first_arg (self, parser);
|
||||
else
|
||||
return gtk_css_image_radial_parse_color_stop (self, parser);
|
||||
|
||||
if (radial->stops->len < 2)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_radial_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageRadial *self = GTK_CSS_IMAGE_RADIAL (image);
|
||||
|
||||
if (gtk_css_parser_has_function (parser, "repeating-radial-gradient"))
|
||||
self->repeating = TRUE;
|
||||
else if (gtk_css_parser_has_function (parser, "radial-gradient"))
|
||||
self->repeating = FALSE;
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "%s() needs at least 2 color stops.",
|
||||
radial->repeating ? "repeating-radial-gradient" : "radial-gradient");
|
||||
gtk_css_parser_error_syntax (parser, "Not a radial gradient");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing bracket at end of radial gradient");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return gtk_css_parser_consume_function (parser, 3, G_MAXUINT, gtk_css_image_radial_parse_arg, self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+33
-38
@@ -155,8 +155,8 @@ gtk_css_image_recolor_load (GtkCssImageRecolor *recolor,
|
||||
|
||||
uri = g_file_get_uri (recolor->file);
|
||||
g_set_error (gerror,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_FAILED,
|
||||
GTK_CSS_PARSER_ERROR,
|
||||
GTK_CSS_PARSER_ERROR_FAILED,
|
||||
"Error loading image '%s': %s", uri, local_error->message);
|
||||
g_free (uri);
|
||||
}
|
||||
@@ -235,49 +235,44 @@ gtk_css_image_recolor_compute (GtkCssImage *image,
|
||||
return img;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_recolor_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssImageRecolor *self = data;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
self->file = gtk_css_parser_consume_url (parser);
|
||||
if (self->file == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
self->palette = gtk_css_palette_value_parse (parser);
|
||||
if (self->palette == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_recolor_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (image);
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "-gtk-recolor", TRUE))
|
||||
if (!gtk_css_parser_has_function (parser, "-gtk-recolor"))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'-gtk-recolor'");
|
||||
gtk_css_parser_error_syntax (parser, "Expected '-gtk-recolor('");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected '(' after '-gtk-recolor'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
recolor->file = _gtk_css_parser_read_url (parser);
|
||||
if (recolor->file == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a url here");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( _gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
recolor->palette = gtk_css_palette_value_parse (parser);
|
||||
if (recolor->palette == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "A palette is required here");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected ')' at end of '-gtk-recolor'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return gtk_css_parser_consume_function (parser, 1, 2, gtk_css_image_recolor_parse_arg, image);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
+42
-56
@@ -143,76 +143,62 @@ gtk_css_image_scaled_compute (GtkCssImage *image,
|
||||
return GTK_CSS_IMAGE (res);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GPtrArray *images;
|
||||
GArray *scales;
|
||||
} GtkCssImageScaledParseData;
|
||||
|
||||
static guint
|
||||
gtk_css_image_scaled_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
{
|
||||
GtkCssImageScaledParseData *data = data_;
|
||||
GtkCssImage *child;
|
||||
int scale;
|
||||
|
||||
child = _gtk_css_image_new_parse (parser);
|
||||
if (child == NULL)
|
||||
return 0;
|
||||
|
||||
if (!gtk_css_parser_has_integer (parser))
|
||||
scale = arg > 0 ? g_array_index (data->scales, int, arg - 1) + 1 : 1;
|
||||
else if (!gtk_css_parser_consume_integer (parser, &scale))
|
||||
return 0;
|
||||
|
||||
g_ptr_array_add (data->images, child);
|
||||
g_array_append_val (data->scales, scale);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_scaled_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image);
|
||||
GPtrArray *images;
|
||||
GArray *scales;
|
||||
int last_scale;
|
||||
GtkCssImage *child;
|
||||
GtkCssImageScaled *self = GTK_CSS_IMAGE_SCALED (image);
|
||||
GtkCssImageScaledParseData data;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "-gtk-scaled", TRUE))
|
||||
if (!gtk_css_parser_has_function (parser, "-gtk-scaled"))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'-gtk-scaled'");
|
||||
gtk_css_parser_error_syntax (parser, "Expected '-gtk-scaled('");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
data.images = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
data.scales = g_array_new (FALSE, FALSE, sizeof (int));
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, G_MAXUINT, gtk_css_image_scaled_parse_arg, &data))
|
||||
{
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected '(' after '-gtk-scaled'");
|
||||
g_ptr_array_unref (data.images);
|
||||
g_array_unref (data.scales);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
images = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
scales = g_array_new (FALSE, FALSE, sizeof (int));
|
||||
|
||||
last_scale = 0;
|
||||
do
|
||||
{
|
||||
child = _gtk_css_image_new_parse (parser);
|
||||
if (child == NULL)
|
||||
{
|
||||
g_ptr_array_free (images, TRUE);
|
||||
g_array_free (scales, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
g_ptr_array_add (images, child);
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
last_scale += 1;
|
||||
g_array_append_val (scales, last_scale);
|
||||
break;
|
||||
}
|
||||
else if (_gtk_css_parser_try_int (parser, &last_scale))
|
||||
{
|
||||
g_array_append_val (scales, last_scale);
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_scale += 1;
|
||||
g_array_append_val (scales, last_scale);
|
||||
}
|
||||
}
|
||||
while (TRUE);
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
g_ptr_array_free (images, TRUE);
|
||||
g_array_free (scales, TRUE);
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected ')' at end of '-gtk-scaled'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
scaled->n_images = images->len;
|
||||
scaled->images = (GtkCssImage **) g_ptr_array_free (images, FALSE);
|
||||
scaled->scales = (int *) g_array_free (scales, FALSE);
|
||||
self->n_images = data.images->len;
|
||||
self->images = (GtkCssImage **) g_ptr_array_free (data.images, FALSE);
|
||||
self->scales = (int *) g_array_free (data.scales, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ gtk_css_image_url_load_image (GtkCssImageUrl *url,
|
||||
|
||||
uri = g_file_get_uri (url->file);
|
||||
g_set_error (error,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_FAILED,
|
||||
GTK_CSS_PARSER_ERROR,
|
||||
GTK_CSS_PARSER_ERROR_FAILED,
|
||||
"Error loading image '%s': %s", uri, local_error->message);
|
||||
g_free (uri);
|
||||
}
|
||||
@@ -165,7 +165,7 @@ gtk_css_image_url_parse (GtkCssImage *image,
|
||||
{
|
||||
GtkCssImageUrl *url = GTK_CSS_IMAGE_URL (image);
|
||||
|
||||
url->file = _gtk_css_parser_read_url (parser);
|
||||
url->file = gtk_css_parser_consume_url (parser);
|
||||
if (url->file == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
+32
-41
@@ -215,40 +215,35 @@ keyframes_set_value (GtkCssKeyframes *keyframes,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_declaration (GtkCssKeyframes *keyframes,
|
||||
guint k,
|
||||
GtkCssParser *parser)
|
||||
gtk_css_keyframes_parse_declaration (GtkCssKeyframes *keyframes,
|
||||
guint k,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkStyleProperty *property;
|
||||
GtkCssValue *value;
|
||||
char *name;
|
||||
|
||||
while (_gtk_css_parser_try (parser, ";", TRUE))
|
||||
{
|
||||
/* SKIP ALL THE THINGS! */
|
||||
}
|
||||
|
||||
name = _gtk_css_parser_try_ident (parser, TRUE);
|
||||
name = gtk_css_parser_consume_ident (parser);
|
||||
if (name == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "No property name given");
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
gtk_css_parser_error_syntax (parser, "Expected a property name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
property = _gtk_style_property_lookup (name);
|
||||
if (property == NULL)
|
||||
{
|
||||
/* should be GTK_CSS_PROVIDER_ERROR_NAME */
|
||||
_gtk_css_parser_error (parser, "No property named '%s'", name);
|
||||
gtk_css_parser_error_value (parser, "No property named '%s'", name);
|
||||
g_free (name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ":", TRUE))
|
||||
if (!gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a ':'");
|
||||
gtk_css_parser_error_syntax (parser, "Expected a ':'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -256,10 +251,9 @@ parse_declaration (GtkCssKeyframes *keyframes,
|
||||
if (value == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ";", TRUE) &&
|
||||
!_gtk_css_parser_begins_with (parser, '}'))
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Junk at end of value");
|
||||
gtk_css_parser_error_syntax (parser, "Junk at end of value");
|
||||
_gtk_css_value_unref (value);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -279,12 +273,12 @@ parse_declaration (GtkCssKeyframes *keyframes,
|
||||
}
|
||||
|
||||
if (!animatable)
|
||||
_gtk_css_parser_error (parser, "shorthand '%s' cannot be animated", _gtk_style_property_get_name (property));
|
||||
gtk_css_parser_error_value (parser, "shorthand '%s' cannot be animated", _gtk_style_property_get_name (property));
|
||||
}
|
||||
else if (GTK_IS_CSS_STYLE_PROPERTY (property))
|
||||
{
|
||||
if (!keyframes_set_value (keyframes, k, GTK_CSS_STYLE_PROPERTY (property), value))
|
||||
_gtk_css_parser_error (parser, "Cannot animate property '%s'", _gtk_style_property_get_name (property));
|
||||
gtk_css_parser_error_value (parser, "Cannot animate property '%s'", _gtk_style_property_get_name (property));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -297,28 +291,27 @@ parse_declaration (GtkCssKeyframes *keyframes,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_block (GtkCssKeyframes *keyframes,
|
||||
guint k,
|
||||
GtkCssParser *parser)
|
||||
gtk_css_keyframes_parse_block (GtkCssKeyframes *keyframes,
|
||||
guint k,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
if (!_gtk_css_parser_try (parser, "{", TRUE))
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_OPEN_CURLY))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected closing bracket after keyframes block");
|
||||
gtk_css_parser_error_syntax (parser, "Expected '{'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (!_gtk_css_parser_try (parser, "}", TRUE))
|
||||
{
|
||||
if (!parse_declaration (keyframes, k, parser))
|
||||
_gtk_css_parser_resync (parser, TRUE, '}');
|
||||
gtk_css_parser_start_block (parser);
|
||||
|
||||
if (_gtk_css_parser_is_eof (parser))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected closing '}' after keyframes block");
|
||||
return FALSE;
|
||||
}
|
||||
while (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_EOF);
|
||||
gtk_css_keyframes_parse_declaration (keyframes, k, parser);
|
||||
gtk_css_parser_end_block (parser);
|
||||
}
|
||||
|
||||
gtk_css_parser_end_block (parser);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -333,19 +326,18 @@ _gtk_css_keyframes_parse (GtkCssParser *parser)
|
||||
|
||||
keyframes = gtk_css_keyframes_new ();
|
||||
|
||||
while (!_gtk_css_parser_begins_with (parser, '}'))
|
||||
while (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "from", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "from"))
|
||||
progress = 0;
|
||||
else if (_gtk_css_parser_try (parser, "to", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "to"))
|
||||
progress = 1;
|
||||
else if (_gtk_css_parser_try_double (parser, &progress) &&
|
||||
_gtk_css_parser_try (parser, "%", TRUE))
|
||||
else if (gtk_css_parser_consume_percentage (parser, &progress))
|
||||
{
|
||||
if (progress < 0 || progress > 100)
|
||||
{
|
||||
/* XXX: should we skip over the block here? */
|
||||
_gtk_css_parser_error (parser, "percentages must be between 0%% and 100%%");
|
||||
gtk_css_parser_error_value (parser, "percentages must be between 0%% and 100%%");
|
||||
_gtk_css_keyframes_unref (keyframes);
|
||||
return NULL;
|
||||
}
|
||||
@@ -353,14 +345,13 @@ _gtk_css_keyframes_parse (GtkCssParser *parser)
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "expected a percentage");
|
||||
_gtk_css_keyframes_unref (keyframes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
k = gtk_css_keyframes_add_keyframe (keyframes, progress);
|
||||
|
||||
if (!parse_block (keyframes, k, parser))
|
||||
if (!gtk_css_keyframes_parse_block (keyframes, k, parser))
|
||||
{
|
||||
_gtk_css_keyframes_unref (keyframes);
|
||||
return NULL;
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
#define __GTK_CSS_LOOKUP_PRIVATE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "gtk/gtkbitmaskprivate.h"
|
||||
#include "gtk/gtkcssstaticstyleprivate.h"
|
||||
#include "gtk/gtkcsssection.h"
|
||||
|
||||
#include "gtk/css/gtkcsssection.h"
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "gtkcssnodeprivate.h"
|
||||
|
||||
#include "gtkcssanimatedstyleprivate.h"
|
||||
#include "gtkcsssectionprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
|
||||
+10
-3
@@ -129,15 +129,22 @@ gtk_css_number_value_transition (GtkCssValue *start,
|
||||
gboolean
|
||||
gtk_css_number_value_can_parse (GtkCssParser *parser)
|
||||
{
|
||||
return _gtk_css_parser_has_number (parser)
|
||||
|| _gtk_css_parser_has_prefix (parser, "calc");
|
||||
return gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_NUMBER)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNLESS_NUMBER)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_INTEGER)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNLESS_INTEGER)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_PERCENTAGE)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION)
|
||||
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_DIMENSION)
|
||||
|| gtk_css_parser_has_function (parser, "calc");
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_number_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
{
|
||||
if (_gtk_css_parser_has_prefix (parser, "calc"))
|
||||
if (gtk_css_parser_has_function (parser, "calc"))
|
||||
return gtk_css_calc_value_parse (parser, flags);
|
||||
|
||||
return gtk_css_dimension_value_parse (parser, flags);
|
||||
|
||||
@@ -216,16 +216,15 @@ gtk_css_palette_value_parse (GtkCssParser *parser)
|
||||
GtkCssValue *result, *color;
|
||||
char *ident;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "default", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "default"))
|
||||
return gtk_css_palette_value_new_default ();
|
||||
|
||||
result = gtk_css_palette_value_new_empty ();
|
||||
|
||||
do {
|
||||
ident = _gtk_css_parser_try_ident (parser, TRUE);
|
||||
ident = gtk_css_parser_consume_ident (parser);
|
||||
if (ident == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "expected color name");
|
||||
_gtk_css_value_unref (result);
|
||||
return NULL;
|
||||
}
|
||||
@@ -240,7 +239,7 @@ gtk_css_palette_value_parse (GtkCssParser *parser)
|
||||
|
||||
gtk_css_palette_value_add_color (result, ident, color);
|
||||
g_free (ident);
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -19,908 +19,6 @@
|
||||
|
||||
#include "gtkcssparserprivate.h"
|
||||
|
||||
#include "gtkcssdimensionvalueprivate.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
/* just for the errors, yay! */
|
||||
#include "gtkcssprovider.h"
|
||||
|
||||
#define NEWLINE_CHARS "\r\n"
|
||||
#define WHITESPACE_CHARS "\f \t"
|
||||
#define NMSTART "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
#define NMCHAR NMSTART "01234567890-_"
|
||||
#define URLCHAR NMCHAR "!#$%&*~"
|
||||
|
||||
#define GTK_IS_CSS_PARSER(parser) ((parser) != NULL)
|
||||
|
||||
struct _GtkCssParser
|
||||
{
|
||||
const char *data;
|
||||
GFile *file;
|
||||
GtkCssParserErrorFunc error_func;
|
||||
gpointer user_data;
|
||||
|
||||
const char *line_start;
|
||||
guint line;
|
||||
|
||||
/* Use this for parsing identifiers, names and strings. */
|
||||
GString *ident_str;
|
||||
};
|
||||
|
||||
GtkCssParser *
|
||||
_gtk_css_parser_new (const char *data,
|
||||
GFile *file,
|
||||
GtkCssParserErrorFunc error_func,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssParser *parser;
|
||||
|
||||
g_return_val_if_fail (data != NULL, NULL);
|
||||
g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
|
||||
|
||||
parser = g_slice_new0 (GtkCssParser);
|
||||
|
||||
parser->data = data;
|
||||
if (file)
|
||||
parser->file = g_object_ref (file);
|
||||
parser->error_func = error_func;
|
||||
parser->user_data = user_data;
|
||||
|
||||
parser->line_start = data;
|
||||
parser->line = 0;
|
||||
|
||||
parser->ident_str = NULL;
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_parser_free (GtkCssParser *parser)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CSS_PARSER (parser));
|
||||
|
||||
if (parser->file)
|
||||
g_object_unref (parser->file);
|
||||
|
||||
if (parser->ident_str)
|
||||
g_string_free (parser->ident_str, TRUE);
|
||||
|
||||
g_slice_free (GtkCssParser, parser);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_is_eof (GtkCssParser *parser)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), TRUE);
|
||||
|
||||
return *parser->data == 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_begins_with (GtkCssParser *parser,
|
||||
char c)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), TRUE);
|
||||
|
||||
return *parser->data == c;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_has_prefix (GtkCssParser *parser,
|
||||
const char *prefix)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), FALSE);
|
||||
|
||||
return g_ascii_strncasecmp (parser->data, prefix, strlen (prefix)) == 0;
|
||||
}
|
||||
|
||||
guint
|
||||
_gtk_css_parser_get_line (GtkCssParser *parser)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), 1);
|
||||
|
||||
return parser->line;
|
||||
}
|
||||
|
||||
guint
|
||||
_gtk_css_parser_get_position (GtkCssParser *parser)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), 1);
|
||||
|
||||
return parser->data - parser->line_start;
|
||||
}
|
||||
|
||||
static GFile *
|
||||
gtk_css_parser_get_base_file (GtkCssParser *parser)
|
||||
{
|
||||
GFile *base;
|
||||
|
||||
if (parser->file)
|
||||
{
|
||||
base = g_file_get_parent (parser->file);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *dir = g_get_current_dir ();
|
||||
base = g_file_new_for_path (dir);
|
||||
g_free (dir);
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
GFile *
|
||||
_gtk_css_parser_get_file_for_path (GtkCssParser *parser,
|
||||
const char *path)
|
||||
{
|
||||
GFile *base, *file;
|
||||
|
||||
g_return_val_if_fail (parser != NULL, NULL);
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
|
||||
base = gtk_css_parser_get_base_file (parser);
|
||||
file = g_file_resolve_relative_path (base, path);
|
||||
g_object_unref (base);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
GFile *
|
||||
_gtk_css_parser_get_file (GtkCssParser *parser)
|
||||
{
|
||||
g_return_val_if_fail (parser != NULL, NULL);
|
||||
|
||||
return parser->file;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_parser_take_error (GtkCssParser *parser,
|
||||
GError *error)
|
||||
{
|
||||
parser->error_func (parser, error, parser->user_data);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_parser_error (GtkCssParser *parser,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
error = g_error_new_valist (GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
format, args);
|
||||
va_end (args);
|
||||
|
||||
_gtk_css_parser_take_error (parser, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_parser_new_line (GtkCssParser *parser)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
if (*parser->data == '\r')
|
||||
{
|
||||
result = TRUE;
|
||||
parser->data++;
|
||||
}
|
||||
if (*parser->data == '\n')
|
||||
{
|
||||
result = TRUE;
|
||||
parser->data++;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
parser->line++;
|
||||
parser->line_start = parser->data;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_parser_skip_comment (GtkCssParser *parser)
|
||||
{
|
||||
if (parser->data[0] != '/' ||
|
||||
parser->data[1] != '*')
|
||||
return FALSE;
|
||||
|
||||
parser->data += 2;
|
||||
|
||||
while (*parser->data)
|
||||
{
|
||||
gsize len = strcspn (parser->data, NEWLINE_CHARS "/");
|
||||
|
||||
parser->data += len;
|
||||
|
||||
if (gtk_css_parser_new_line (parser))
|
||||
continue;
|
||||
|
||||
parser->data++;
|
||||
|
||||
if (len > 0 && parser->data[-2] == '*')
|
||||
return TRUE;
|
||||
if (parser->data[0] == '*')
|
||||
_gtk_css_parser_error (parser, "'/*' in comment block");
|
||||
}
|
||||
|
||||
/* FIXME: position */
|
||||
_gtk_css_parser_error (parser, "Unterminated comment");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_parser_skip_whitespace (GtkCssParser *parser)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
while (*parser->data)
|
||||
{
|
||||
if (gtk_css_parser_new_line (parser))
|
||||
continue;
|
||||
|
||||
len = strspn (parser->data, WHITESPACE_CHARS);
|
||||
if (len)
|
||||
{
|
||||
parser->data += len;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!gtk_css_parser_skip_comment (parser))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_try (GtkCssParser *parser,
|
||||
const char *string,
|
||||
gboolean skip_whitespace)
|
||||
{
|
||||
gsize string_len;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), FALSE);
|
||||
g_return_val_if_fail (string != NULL, FALSE);
|
||||
|
||||
string_len = strlen (string);
|
||||
|
||||
if (g_ascii_strncasecmp (parser->data, string, string_len) != 0)
|
||||
return FALSE;
|
||||
|
||||
parser->data += string_len;
|
||||
|
||||
if (skip_whitespace)
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
get_xdigit (char c)
|
||||
{
|
||||
if (c >= 'a')
|
||||
return c - 'a' + 10;
|
||||
else if (c >= 'A')
|
||||
return c - 'A' + 10;
|
||||
else
|
||||
return c - '0';
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_parser_unescape (GtkCssParser *parser,
|
||||
GString *str)
|
||||
{
|
||||
guint i;
|
||||
gunichar result = 0;
|
||||
|
||||
g_assert (*parser->data == '\\');
|
||||
|
||||
parser->data++;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (!g_ascii_isxdigit (parser->data[i]))
|
||||
break;
|
||||
|
||||
result = (result << 4) + get_xdigit (parser->data[i]);
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
g_string_append_unichar (str, result);
|
||||
parser->data += i;
|
||||
|
||||
/* NB: gtk_css_parser_new_line() forward data pointer itself */
|
||||
if (!gtk_css_parser_new_line (parser) &&
|
||||
*parser->data &&
|
||||
strchr (WHITESPACE_CHARS, *parser->data))
|
||||
parser->data++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gtk_css_parser_new_line (parser))
|
||||
return;
|
||||
|
||||
g_string_append_c (str, *parser->data);
|
||||
parser->data++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gtk_css_parser_read_char (GtkCssParser *parser,
|
||||
GString * str,
|
||||
const char * allowed)
|
||||
{
|
||||
if (*parser->data == 0)
|
||||
return FALSE;
|
||||
|
||||
if (strchr (allowed, *parser->data))
|
||||
{
|
||||
g_string_append_c (str, *parser->data);
|
||||
parser->data++;
|
||||
return TRUE;
|
||||
}
|
||||
if (*parser->data >= 127)
|
||||
{
|
||||
gsize len = g_utf8_skip[(guint) *(guchar *) parser->data];
|
||||
|
||||
g_string_append_len (str, parser->data, len);
|
||||
parser->data += len;
|
||||
return TRUE;
|
||||
}
|
||||
if (*parser->data == '\\')
|
||||
{
|
||||
_gtk_css_parser_unescape (parser, str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char *
|
||||
_gtk_css_parser_get_ident (GtkCssParser *parser)
|
||||
{
|
||||
char *result;
|
||||
gsize len;
|
||||
|
||||
len = parser->ident_str->len;
|
||||
|
||||
result = g_new (char, len + 1);
|
||||
memcpy (result, parser->ident_str->str, len + 1);
|
||||
g_string_set_size (parser->ident_str, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
_gtk_css_parser_try_name (GtkCssParser *parser,
|
||||
gboolean skip_whitespace)
|
||||
{
|
||||
GString *name;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL);
|
||||
|
||||
if (parser->ident_str == NULL)
|
||||
parser->ident_str = g_string_new (NULL);
|
||||
|
||||
name = parser->ident_str;
|
||||
|
||||
while (_gtk_css_parser_read_char (parser, name, NMCHAR))
|
||||
;
|
||||
|
||||
if (skip_whitespace)
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
|
||||
return _gtk_css_parser_get_ident (parser);
|
||||
}
|
||||
|
||||
char *
|
||||
_gtk_css_parser_try_ident (GtkCssParser *parser,
|
||||
gboolean skip_whitespace)
|
||||
{
|
||||
const char *start;
|
||||
GString *ident;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL);
|
||||
|
||||
start = parser->data;
|
||||
|
||||
if (parser->ident_str == NULL)
|
||||
parser->ident_str = g_string_new (NULL);
|
||||
|
||||
ident = parser->ident_str;
|
||||
|
||||
if (*parser->data == '-')
|
||||
{
|
||||
g_string_append_c (ident, '-');
|
||||
parser->data++;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_read_char (parser, ident, NMSTART))
|
||||
{
|
||||
parser->data = start;
|
||||
g_string_set_size (ident, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (_gtk_css_parser_read_char (parser, ident, NMCHAR))
|
||||
;
|
||||
|
||||
if (skip_whitespace)
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
|
||||
return _gtk_css_parser_get_ident (parser);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_is_string (GtkCssParser *parser)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), FALSE);
|
||||
|
||||
return *parser->data == '"' || *parser->data == '\'';
|
||||
}
|
||||
|
||||
char *
|
||||
_gtk_css_parser_read_string (GtkCssParser *parser)
|
||||
{
|
||||
GString *str;
|
||||
char quote;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL);
|
||||
|
||||
quote = *parser->data;
|
||||
|
||||
if (quote != '"' && quote != '\'')
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a string.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parser->data++;
|
||||
|
||||
if (parser->ident_str == NULL)
|
||||
parser->ident_str = g_string_new (NULL);
|
||||
|
||||
str = parser->ident_str;
|
||||
g_assert (str->len == 0);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
gsize len = strcspn (parser->data, "\\'\"\n\r\f");
|
||||
|
||||
g_string_append_len (str, parser->data, len);
|
||||
|
||||
parser->data += len;
|
||||
|
||||
switch (*parser->data)
|
||||
{
|
||||
case '\\':
|
||||
_gtk_css_parser_unescape (parser, str);
|
||||
break;
|
||||
case '"':
|
||||
case '\'':
|
||||
if (*parser->data == quote)
|
||||
{
|
||||
parser->data++;
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
return _gtk_css_parser_get_ident (parser);
|
||||
}
|
||||
|
||||
g_string_append_c (str, *parser->data);
|
||||
parser->data++;
|
||||
break;
|
||||
case '\0':
|
||||
/* FIXME: position */
|
||||
_gtk_css_parser_error (parser, "Missing end quote in string.");
|
||||
g_string_set_size (str, 0);
|
||||
return NULL;
|
||||
default:
|
||||
_gtk_css_parser_error (parser,
|
||||
"Invalid character in string. Must be escaped.");
|
||||
g_string_set_size (str, 0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_try_int (GtkCssParser *parser,
|
||||
int *value)
|
||||
{
|
||||
gint64 result;
|
||||
char *end;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
/* strtoll parses a plus, but we are not allowed to */
|
||||
if (*parser->data == '+')
|
||||
return FALSE;
|
||||
|
||||
errno = 0;
|
||||
result = g_ascii_strtoll (parser->data, &end, 10);
|
||||
if (errno)
|
||||
return FALSE;
|
||||
if (result > G_MAXINT || result < G_MININT)
|
||||
return FALSE;
|
||||
if (parser->data == end)
|
||||
return FALSE;
|
||||
|
||||
parser->data = end;
|
||||
*value = result;
|
||||
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_try_double (GtkCssParser *parser,
|
||||
gdouble *value)
|
||||
{
|
||||
gdouble result;
|
||||
char *end;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
errno = 0;
|
||||
result = g_ascii_strtod (parser->data, &end);
|
||||
if (errno)
|
||||
return FALSE;
|
||||
if (parser->data == end)
|
||||
return FALSE;
|
||||
|
||||
parser->data = end;
|
||||
*value = result;
|
||||
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_has_number (GtkCssParser *parser)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (parser->data[0] == '-' || parser->data[0] == '+')
|
||||
c = parser->data[1];
|
||||
else
|
||||
c = parser->data[0];
|
||||
|
||||
/* ahem */
|
||||
return g_ascii_isdigit (c) || c == '.';
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_dimension_value_parse (GtkCssParser *parser,
|
||||
GtkCssNumberParseFlags flags)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
GtkCssUnit unit;
|
||||
GtkCssNumberParseFlags required_flags;
|
||||
} units[] = {
|
||||
{ "px", GTK_CSS_PX, GTK_CSS_PARSE_LENGTH },
|
||||
{ "pt", GTK_CSS_PT, GTK_CSS_PARSE_LENGTH },
|
||||
{ "em", GTK_CSS_EM, GTK_CSS_PARSE_LENGTH },
|
||||
{ "ex", GTK_CSS_EX, GTK_CSS_PARSE_LENGTH },
|
||||
{ "rem", GTK_CSS_REM, GTK_CSS_PARSE_LENGTH },
|
||||
{ "pc", GTK_CSS_PC, GTK_CSS_PARSE_LENGTH },
|
||||
{ "in", GTK_CSS_IN, GTK_CSS_PARSE_LENGTH },
|
||||
{ "cm", GTK_CSS_CM, GTK_CSS_PARSE_LENGTH },
|
||||
{ "mm", GTK_CSS_MM, GTK_CSS_PARSE_LENGTH },
|
||||
{ "rad", GTK_CSS_RAD, GTK_CSS_PARSE_ANGLE },
|
||||
{ "deg", GTK_CSS_DEG, GTK_CSS_PARSE_ANGLE },
|
||||
{ "grad", GTK_CSS_GRAD, GTK_CSS_PARSE_ANGLE },
|
||||
{ "turn", GTK_CSS_TURN, GTK_CSS_PARSE_ANGLE },
|
||||
{ "s", GTK_CSS_S, GTK_CSS_PARSE_TIME },
|
||||
{ "ms", GTK_CSS_MS, GTK_CSS_PARSE_TIME }
|
||||
};
|
||||
char *end, *unit_name;
|
||||
double value;
|
||||
GtkCssUnit unit;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL);
|
||||
|
||||
errno = 0;
|
||||
value = g_ascii_strtod (parser->data, &end);
|
||||
if (errno)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "not a number: %s", g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
if (parser->data == end)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "not a number");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parser->data = end;
|
||||
|
||||
if (flags & GTK_CSS_POSITIVE_ONLY &&
|
||||
value < 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "negative values are not allowed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unit_name = _gtk_css_parser_try_ident (parser, FALSE);
|
||||
|
||||
if (unit_name)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (units); i++)
|
||||
{
|
||||
if (flags & units[i].required_flags &&
|
||||
g_ascii_strcasecmp (unit_name, units[i].name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= G_N_ELEMENTS (units))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'%s' is not a valid unit.", unit_name);
|
||||
g_free (unit_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unit = units[i].unit;
|
||||
|
||||
g_free (unit_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((flags & GTK_CSS_PARSE_PERCENT) &&
|
||||
_gtk_css_parser_try (parser, "%", FALSE))
|
||||
{
|
||||
unit = GTK_CSS_PERCENT;
|
||||
}
|
||||
else if (value == 0.0)
|
||||
{
|
||||
if (flags & GTK_CSS_PARSE_NUMBER)
|
||||
unit = GTK_CSS_NUMBER;
|
||||
else if (flags & GTK_CSS_PARSE_LENGTH)
|
||||
unit = GTK_CSS_PX;
|
||||
else if (flags & GTK_CSS_PARSE_ANGLE)
|
||||
unit = GTK_CSS_DEG;
|
||||
else if (flags & GTK_CSS_PARSE_TIME)
|
||||
unit = GTK_CSS_S;
|
||||
else
|
||||
unit = GTK_CSS_PERCENT;
|
||||
}
|
||||
else if (flags & GTK_CSS_PARSE_NUMBER)
|
||||
{
|
||||
unit = GTK_CSS_NUMBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Unit is missing.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
|
||||
return gtk_css_dimension_value_new (value, unit);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_parser_try_hash_color (GtkCssParser *parser,
|
||||
GdkRGBA *rgba)
|
||||
{
|
||||
if (parser->data[0] == '#' &&
|
||||
g_ascii_isxdigit (parser->data[1]) &&
|
||||
g_ascii_isxdigit (parser->data[2]) &&
|
||||
g_ascii_isxdigit (parser->data[3]))
|
||||
{
|
||||
if (g_ascii_isxdigit (parser->data[4]))
|
||||
{
|
||||
if (g_ascii_isxdigit (parser->data[5]) &&
|
||||
g_ascii_isxdigit (parser->data[6]))
|
||||
{
|
||||
rgba->red = ((get_xdigit (parser->data[1]) << 4) + get_xdigit (parser->data[2])) / 255.0;
|
||||
rgba->green = ((get_xdigit (parser->data[3]) << 4) + get_xdigit (parser->data[4])) / 255.0;
|
||||
rgba->blue = ((get_xdigit (parser->data[5]) << 4) + get_xdigit (parser->data[6])) / 255.0;
|
||||
if (g_ascii_isxdigit (parser->data[7]) &&
|
||||
g_ascii_isxdigit (parser->data[8]))
|
||||
{
|
||||
rgba->alpha = ((get_xdigit (parser->data[7]) << 4) + get_xdigit (parser->data[8])) / 255.0;
|
||||
parser->data += 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgba->alpha = 1.0;
|
||||
parser->data += 7;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rgba->red = get_xdigit (parser->data[1]) / 15.0;
|
||||
rgba->green = get_xdigit (parser->data[2]) / 15.0;
|
||||
rgba->blue = get_xdigit (parser->data[3]) / 15.0;
|
||||
rgba->alpha = get_xdigit (parser->data[4]) / 15.0;
|
||||
parser->data += 5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rgba->red = get_xdigit (parser->data[1]) / 15.0;
|
||||
rgba->green = get_xdigit (parser->data[2]) / 15.0;
|
||||
rgba->blue = get_xdigit (parser->data[3]) / 15.0;
|
||||
rgba->alpha = 1.0;
|
||||
parser->data += 4;
|
||||
}
|
||||
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GFile *
|
||||
_gtk_css_parser_read_url (GtkCssParser *parser)
|
||||
{
|
||||
gchar *path;
|
||||
char *scheme;
|
||||
GFile *file;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "url", FALSE))
|
||||
{
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected '(' after 'url'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path = _gtk_css_parser_read_string (parser);
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "No closing ')' found for 'url'");
|
||||
g_free (path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scheme = g_uri_parse_scheme (path);
|
||||
if (scheme != NULL)
|
||||
{
|
||||
file = g_file_new_for_uri (path);
|
||||
g_free (path);
|
||||
g_free (scheme);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
path = _gtk_css_parser_try_name (parser, TRUE);
|
||||
if (path == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid url");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
file = _gtk_css_parser_get_file_for_path (parser, path);
|
||||
g_free (path);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_parser_resync_internal (GtkCssParser *parser,
|
||||
gboolean sync_at_semicolon,
|
||||
gboolean read_sync_token,
|
||||
char terminator)
|
||||
{
|
||||
gsize len;
|
||||
|
||||
do {
|
||||
len = strcspn (parser->data, "\\\"'/()[]{};" NEWLINE_CHARS);
|
||||
parser->data += len;
|
||||
|
||||
if (gtk_css_parser_new_line (parser))
|
||||
continue;
|
||||
|
||||
if (_gtk_css_parser_is_string (parser))
|
||||
{
|
||||
/* Hrm, this emits errors, and i suspect it shouldn't... */
|
||||
char *free_me = _gtk_css_parser_read_string (parser);
|
||||
g_free (free_me);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gtk_css_parser_skip_comment (parser))
|
||||
continue;
|
||||
|
||||
switch (*parser->data)
|
||||
{
|
||||
case '\\':
|
||||
{
|
||||
GString *ignore = g_string_new (NULL);
|
||||
_gtk_css_parser_unescape (parser, ignore);
|
||||
g_string_free (ignore, TRUE);
|
||||
}
|
||||
break;
|
||||
case ';':
|
||||
if (sync_at_semicolon && !read_sync_token)
|
||||
return;
|
||||
parser->data++;
|
||||
if (sync_at_semicolon)
|
||||
{
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
parser->data++;
|
||||
_gtk_css_parser_resync (parser, FALSE, ')');
|
||||
if (*parser->data)
|
||||
parser->data++;
|
||||
break;
|
||||
case '[':
|
||||
parser->data++;
|
||||
_gtk_css_parser_resync (parser, FALSE, ']');
|
||||
if (*parser->data)
|
||||
parser->data++;
|
||||
break;
|
||||
case '{':
|
||||
parser->data++;
|
||||
_gtk_css_parser_resync (parser, FALSE, '}');
|
||||
if (*parser->data)
|
||||
parser->data++;
|
||||
if (sync_at_semicolon || !terminator)
|
||||
{
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
case ')':
|
||||
case ']':
|
||||
if (terminator == *parser->data)
|
||||
{
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
return;
|
||||
}
|
||||
parser->data++;
|
||||
continue;
|
||||
case '\0':
|
||||
break;
|
||||
case '/':
|
||||
default:
|
||||
parser->data++;
|
||||
break;
|
||||
}
|
||||
} while (*parser->data);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_parser_resync (GtkCssParser *parser,
|
||||
gboolean sync_at_semicolon,
|
||||
char terminator)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CSS_PARSER (parser));
|
||||
|
||||
gtk_css_parser_resync_internal (parser, sync_at_semicolon, TRUE, terminator);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_print_string (GString *str,
|
||||
const char *string)
|
||||
|
||||
@@ -20,70 +20,12 @@
|
||||
|
||||
#include <gtk/gtkcssprovider.h>
|
||||
|
||||
#include <gtk/css/gtkcss.h>
|
||||
#include "gtk/css/gtkcsstokenizerprivate.h"
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkCssParser GtkCssParser;
|
||||
|
||||
typedef void (* GtkCssParserErrorFunc) (GtkCssParser *parser,
|
||||
const GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
GtkCssParser * _gtk_css_parser_new (const char *data,
|
||||
GFile *file,
|
||||
GtkCssParserErrorFunc error_func,
|
||||
gpointer user_data);
|
||||
void _gtk_css_parser_free (GtkCssParser *parser);
|
||||
|
||||
void _gtk_css_parser_take_error (GtkCssParser *parser,
|
||||
GError *error);
|
||||
void _gtk_css_parser_error (GtkCssParser *parser,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (2, 3);
|
||||
|
||||
guint _gtk_css_parser_get_line (GtkCssParser *parser);
|
||||
guint _gtk_css_parser_get_position (GtkCssParser *parser);
|
||||
GFile * _gtk_css_parser_get_file (GtkCssParser *parser);
|
||||
GFile * _gtk_css_parser_get_file_for_path (GtkCssParser *parser,
|
||||
const char *path);
|
||||
|
||||
gboolean _gtk_css_parser_is_eof (GtkCssParser *parser);
|
||||
gboolean _gtk_css_parser_begins_with (GtkCssParser *parser,
|
||||
char c);
|
||||
gboolean _gtk_css_parser_has_prefix (GtkCssParser *parser,
|
||||
const char *prefix);
|
||||
gboolean _gtk_css_parser_is_string (GtkCssParser *parser);
|
||||
|
||||
/* IMPORTANT:
|
||||
* _try_foo() functions do not modify the data pointer if they fail, nor do they
|
||||
* signal an error. _read_foo() will modify the data pointer and position it at
|
||||
* the first token that is broken and emit an error about the failure.
|
||||
* So only call _read_foo() when you know that you are reading a foo. _try_foo()
|
||||
* however is fine to call if you don’t know yet if the token is a foo or a bar,
|
||||
* you can _try_bar() if try_foo() failed.
|
||||
*/
|
||||
gboolean _gtk_css_parser_try (GtkCssParser *parser,
|
||||
const char *string,
|
||||
gboolean skip_whitespace);
|
||||
char * _gtk_css_parser_try_ident (GtkCssParser *parser,
|
||||
gboolean skip_whitespace);
|
||||
char * _gtk_css_parser_try_name (GtkCssParser *parser,
|
||||
gboolean skip_whitespace);
|
||||
gboolean _gtk_css_parser_try_int (GtkCssParser *parser,
|
||||
int *value);
|
||||
gboolean _gtk_css_parser_try_double (GtkCssParser *parser,
|
||||
gdouble *value);
|
||||
gboolean _gtk_css_parser_try_hash_color (GtkCssParser *parser,
|
||||
GdkRGBA *rgba);
|
||||
|
||||
gboolean _gtk_css_parser_has_number (GtkCssParser *parser);
|
||||
char * _gtk_css_parser_read_string (GtkCssParser *parser);
|
||||
GFile * _gtk_css_parser_read_url (GtkCssParser *parser);
|
||||
|
||||
void _gtk_css_parser_skip_whitespace (GtkCssParser *parser);
|
||||
void _gtk_css_parser_resync (GtkCssParser *parser,
|
||||
gboolean sync_at_semicolon,
|
||||
char terminator);
|
||||
|
||||
/* XXX: Find better place to put it? */
|
||||
void _gtk_css_print_string (GString *str,
|
||||
const char *string);
|
||||
|
||||
+48
-42
@@ -179,42 +179,34 @@ position_value_parse (GtkCssParser *parser, gboolean try)
|
||||
const char *name;
|
||||
guint percentage;
|
||||
gboolean horizontal;
|
||||
gboolean vertical;
|
||||
gboolean swap;
|
||||
} names[] = {
|
||||
{ "left", 0, TRUE, FALSE },
|
||||
{ "right", 100, TRUE, FALSE },
|
||||
{ "center", 50, TRUE, TRUE },
|
||||
{ "top", 0, FALSE, TRUE },
|
||||
{ "bottom", 100, FALSE, TRUE },
|
||||
{ NULL , 0, TRUE, FALSE }, /* used for numbers */
|
||||
{ NULL , 50, TRUE, TRUE } /* used for no value */
|
||||
{ "top", 0, FALSE, FALSE },
|
||||
{ "bottom", 100, FALSE, FALSE },
|
||||
};
|
||||
GtkCssValue *x, *y;
|
||||
GtkCssValue **missing;
|
||||
guint first, second;
|
||||
GtkCssValue *x = NULL, *y = NULL;
|
||||
gboolean swap = FALSE;
|
||||
guint i;
|
||||
|
||||
for (first = 0; names[first].name != NULL; first++)
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, names[first].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, names[i].name))
|
||||
{
|
||||
if (names[first].horizontal)
|
||||
{
|
||||
x = _gtk_css_number_value_new (names[first].percentage, GTK_CSS_PERCENT);
|
||||
missing = &y;
|
||||
}
|
||||
if (names[i].horizontal)
|
||||
x = _gtk_css_number_value_new (names[i].percentage, GTK_CSS_PERCENT);
|
||||
else
|
||||
{
|
||||
y = _gtk_css_number_value_new (names[first].percentage, GTK_CSS_PERCENT);
|
||||
missing = &x;
|
||||
}
|
||||
y = _gtk_css_number_value_new (names[i].percentage, GTK_CSS_PERCENT);
|
||||
swap = names[i].swap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (names[first].name == NULL)
|
||||
if (i == G_N_ELEMENTS (names))
|
||||
{
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
missing = &y;
|
||||
x = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_PERCENT
|
||||
| GTK_CSS_PARSE_LENGTH);
|
||||
@@ -225,28 +217,52 @@ position_value_parse (GtkCssParser *parser, gboolean try)
|
||||
else
|
||||
{
|
||||
if (!try)
|
||||
_gtk_css_parser_error (parser, "Unrecognized position value");
|
||||
gtk_css_parser_error_syntax (parser, "Unrecognized position value");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (second = 0; names[second].name != NULL; second++)
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, names[second].name, TRUE))
|
||||
if (!swap && !names[i].swap)
|
||||
{
|
||||
*missing = _gtk_css_number_value_new (names[second].percentage, GTK_CSS_PERCENT);
|
||||
if (names[i].horizontal && x != NULL)
|
||||
continue;
|
||||
if (!names[i].horizontal && y != NULL)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, names[i].name))
|
||||
{
|
||||
if (x)
|
||||
{
|
||||
if (names[i].horizontal && !names[i].swap)
|
||||
{
|
||||
y = x;
|
||||
x = _gtk_css_number_value_new (names[i].percentage, GTK_CSS_PERCENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
y = _gtk_css_number_value_new (names[i].percentage, GTK_CSS_PERCENT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (names[i].horizontal || names[i].swap);
|
||||
x = _gtk_css_number_value_new (names[i].percentage, GTK_CSS_PERCENT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (names[second].name == NULL)
|
||||
if (i == G_N_ELEMENTS (names))
|
||||
{
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
if (missing != &y)
|
||||
if (y != NULL)
|
||||
{
|
||||
if (!try)
|
||||
_gtk_css_parser_error (parser, "Invalid combination of values");
|
||||
gtk_css_parser_error_syntax (parser, "Invalid combination of values");
|
||||
_gtk_css_value_unref (y);
|
||||
return NULL;
|
||||
}
|
||||
@@ -261,20 +277,10 @@ position_value_parse (GtkCssParser *parser, gboolean try)
|
||||
}
|
||||
else
|
||||
{
|
||||
second++;
|
||||
*missing = _gtk_css_number_value_new (50, GTK_CSS_PERCENT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((names[first].horizontal && !names[second].vertical) ||
|
||||
(!names[first].horizontal && !names[second].horizontal))
|
||||
{
|
||||
if (!try)
|
||||
_gtk_css_parser_error (parser, "Invalid combination of values");
|
||||
_gtk_css_value_unref (x);
|
||||
_gtk_css_value_unref (y);
|
||||
return NULL;
|
||||
if (y)
|
||||
x = _gtk_css_number_value_new (50, GTK_CSS_PERCENT);
|
||||
else
|
||||
y = _gtk_css_number_value_new (50, GTK_CSS_PERCENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+177
-411
@@ -17,12 +17,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "gtkcssproviderprivate.h"
|
||||
|
||||
#include "gtkbitmaskprivate.h"
|
||||
@@ -30,7 +24,6 @@
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcsskeyframesprivate.h"
|
||||
#include "gtkcssparserprivate.h"
|
||||
#include "gtkcsssectionprivate.h"
|
||||
#include "gtkcssselectorprivate.h"
|
||||
#include "gtkcssshorthandpropertyprivate.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
@@ -45,6 +38,12 @@
|
||||
#include "gtkintl.h"
|
||||
#include "gtkversion.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
/**
|
||||
* SECTION:gtkcssprovider
|
||||
* @Short_description: CSS-like styling for widgets
|
||||
@@ -103,7 +102,6 @@ struct _GtkCssScanner
|
||||
{
|
||||
GtkCssProvider *provider;
|
||||
GtkCssParser *parser;
|
||||
GtkCssSection *section;
|
||||
GtkCssScanner *parent;
|
||||
GSList *state;
|
||||
};
|
||||
@@ -140,13 +138,7 @@ static void
|
||||
gtk_css_provider_load_internal (GtkCssProvider *css_provider,
|
||||
GtkCssScanner *scanner,
|
||||
GFile *file,
|
||||
const char *data);
|
||||
|
||||
GQuark
|
||||
gtk_css_provider_error_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gtk-css-provider-error-quark");
|
||||
}
|
||||
GBytes *bytes);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (GtkCssProvider, gtk_css_provider, G_TYPE_OBJECT, 0,
|
||||
G_ADD_PRIVATE (GtkCssProvider)
|
||||
@@ -169,7 +161,7 @@ gtk_css_provider_parsing_error (GtkCssProvider *provider,
|
||||
0,
|
||||
TRUE))
|
||||
{
|
||||
char *s = _gtk_css_section_to_string (section);
|
||||
char *s = gtk_css_section_to_string (section);
|
||||
|
||||
g_warning ("Theme parsing error: %s: %s",
|
||||
s,
|
||||
@@ -315,10 +307,8 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset,
|
||||
static void
|
||||
gtk_css_scanner_destroy (GtkCssScanner *scanner)
|
||||
{
|
||||
if (scanner->section)
|
||||
gtk_css_section_unref (scanner->section);
|
||||
g_object_unref (scanner->provider);
|
||||
_gtk_css_parser_free (scanner->parser);
|
||||
gtk_css_parser_unref (scanner->parser);
|
||||
|
||||
g_slice_free (GtkCssScanner, scanner);
|
||||
}
|
||||
@@ -332,31 +322,29 @@ gtk_css_style_provider_emit_error (GtkStyleProvider *provider,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_provider_emit_error (GtkCssProvider *provider,
|
||||
GtkCssScanner *scanner,
|
||||
const GError *error)
|
||||
{
|
||||
gtk_css_style_provider_emit_error (GTK_STYLE_PROVIDER (provider),
|
||||
scanner ? scanner->section : NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_scanner_parser_error (GtkCssParser *parser,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
gtk_css_scanner_parser_error (GtkCssParser *parser,
|
||||
const GtkCssLocation *start,
|
||||
const GtkCssLocation *end,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssScanner *scanner = user_data;
|
||||
GtkCssSection *section;
|
||||
|
||||
gtk_css_provider_emit_error (scanner->provider, scanner, error);
|
||||
section = gtk_css_section_new (gtk_css_parser_get_file (parser),
|
||||
start,
|
||||
end);
|
||||
|
||||
gtk_css_style_provider_emit_error (GTK_STYLE_PROVIDER (scanner->provider), section, error);
|
||||
|
||||
gtk_css_section_unref (section);
|
||||
}
|
||||
|
||||
static GtkCssScanner *
|
||||
gtk_css_scanner_new (GtkCssProvider *provider,
|
||||
GtkCssScanner *parent,
|
||||
GtkCssSection *section,
|
||||
GFile *file,
|
||||
const gchar *text)
|
||||
GBytes *bytes)
|
||||
{
|
||||
GtkCssScanner *scanner;
|
||||
|
||||
@@ -365,13 +353,13 @@ gtk_css_scanner_new (GtkCssProvider *provider,
|
||||
g_object_ref (provider);
|
||||
scanner->provider = provider;
|
||||
scanner->parent = parent;
|
||||
if (section)
|
||||
scanner->section = gtk_css_section_ref (section);
|
||||
|
||||
scanner->parser = _gtk_css_parser_new (text,
|
||||
file,
|
||||
gtk_css_scanner_parser_error,
|
||||
scanner);
|
||||
scanner->parser = gtk_css_parser_new_for_bytes (bytes,
|
||||
file,
|
||||
NULL,
|
||||
gtk_css_scanner_parser_error,
|
||||
scanner,
|
||||
NULL);
|
||||
|
||||
return scanner;
|
||||
}
|
||||
@@ -382,7 +370,7 @@ gtk_css_scanner_would_recurse (GtkCssScanner *scanner,
|
||||
{
|
||||
while (scanner)
|
||||
{
|
||||
GFile *parser_file = _gtk_css_parser_get_file (scanner->parser);
|
||||
GFile *parser_file = gtk_css_parser_get_file (scanner->parser);
|
||||
if (parser_file && g_file_equal (parser_file, file))
|
||||
return TRUE;
|
||||
|
||||
@@ -392,39 +380,6 @@ gtk_css_scanner_would_recurse (GtkCssScanner *scanner,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_scanner_push_section (GtkCssScanner *scanner,
|
||||
GtkCssSectionType section_type)
|
||||
{
|
||||
GtkCssSection *section;
|
||||
|
||||
section = _gtk_css_section_new (scanner->section,
|
||||
section_type,
|
||||
scanner->parser);
|
||||
|
||||
if (scanner->section)
|
||||
gtk_css_section_unref (scanner->section);
|
||||
scanner->section = section;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_scanner_pop_section (GtkCssScanner *scanner,
|
||||
GtkCssSectionType check_type)
|
||||
{
|
||||
GtkCssSection *parent;
|
||||
|
||||
g_assert (gtk_css_section_get_section_type (scanner->section) == check_type);
|
||||
|
||||
parent = gtk_css_section_get_parent (scanner->section);
|
||||
if (parent)
|
||||
gtk_css_section_ref (parent);
|
||||
|
||||
_gtk_css_section_end (scanner->section);
|
||||
gtk_css_section_unref (scanner->section);
|
||||
|
||||
scanner->section = parent;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_provider_init (GtkCssProvider *css_provider)
|
||||
{
|
||||
@@ -664,67 +619,6 @@ gtk_css_provider_new (void)
|
||||
return g_object_new (GTK_TYPE_CSS_PROVIDER, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_provider_take_error (GtkCssProvider *provider,
|
||||
GtkCssScanner *scanner,
|
||||
GError *error)
|
||||
{
|
||||
gtk_css_provider_emit_error (provider, scanner, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_provider_error_literal (GtkCssProvider *provider,
|
||||
GtkCssScanner *scanner,
|
||||
GQuark domain,
|
||||
gint code,
|
||||
const char *message)
|
||||
{
|
||||
gtk_css_provider_take_error (provider,
|
||||
scanner,
|
||||
g_error_new_literal (domain, code, message));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_provider_error (GtkCssProvider *provider,
|
||||
GtkCssScanner *scanner,
|
||||
GQuark domain,
|
||||
gint code,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (5, 6);
|
||||
static void
|
||||
gtk_css_provider_error (GtkCssProvider *provider,
|
||||
GtkCssScanner *scanner,
|
||||
GQuark domain,
|
||||
gint code,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
GError *error;
|
||||
va_list args;
|
||||
|
||||
gtk_internal_return_if_fail (GTK_IS_CSS_PROVIDER (provider));
|
||||
gtk_internal_return_if_fail (scanner != NULL);
|
||||
|
||||
va_start (args, format);
|
||||
error = g_error_new_valist (domain, code, format, args);
|
||||
va_end (args);
|
||||
|
||||
gtk_css_provider_take_error (provider, scanner, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_provider_invalid_token (GtkCssProvider *provider,
|
||||
GtkCssScanner *scanner,
|
||||
const char *expected)
|
||||
{
|
||||
gtk_css_provider_error (provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"expected %s", expected);
|
||||
}
|
||||
|
||||
static void
|
||||
css_provider_commit (GtkCssProvider *css_provider,
|
||||
GSList *selectors,
|
||||
@@ -772,7 +666,6 @@ gtk_css_provider_reset (GtkCssProvider *css_provider)
|
||||
g_array_set_size (priv->rulesets, 0);
|
||||
_gtk_css_selector_tree_free (priv->tree);
|
||||
priv->tree = NULL;
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -780,48 +673,50 @@ parse_import (GtkCssScanner *scanner)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_IMPORT);
|
||||
if (!gtk_css_parser_try_at_keyword (scanner->parser, "import"))
|
||||
return FALSE;
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, "@import", TRUE))
|
||||
if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_STRING))
|
||||
{
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_IMPORT);
|
||||
return FALSE;
|
||||
}
|
||||
char *url;
|
||||
|
||||
if (_gtk_css_parser_is_string (scanner->parser))
|
||||
{
|
||||
char *uri;
|
||||
|
||||
uri = _gtk_css_parser_read_string (scanner->parser);
|
||||
file = _gtk_css_parser_get_file_for_path (scanner->parser, uri);
|
||||
g_free (uri);
|
||||
url = gtk_css_parser_consume_string (scanner->parser);
|
||||
if (url)
|
||||
{
|
||||
file = gtk_css_parser_resolve_url (scanner->parser, url);
|
||||
if (file == NULL)
|
||||
{
|
||||
gtk_css_parser_error_import (scanner->parser,
|
||||
"Could not resolve \"%s\" to a valid URL",
|
||||
url);
|
||||
}
|
||||
g_free (url);
|
||||
}
|
||||
else
|
||||
file = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
file = _gtk_css_parser_read_url (scanner->parser);
|
||||
file = gtk_css_parser_consume_url (scanner->parser);
|
||||
}
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, 0);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_IMPORT);
|
||||
return TRUE;
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, ";", FALSE))
|
||||
else if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_provider_invalid_token (scanner->provider, scanner, "semicolon");
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, 0);
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Expected ';'");
|
||||
}
|
||||
else if (gtk_css_scanner_would_recurse (scanner, file))
|
||||
{
|
||||
char *path = g_file_get_path (file);
|
||||
gtk_css_provider_error (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_IMPORT,
|
||||
"Loading '%s' would recurse",
|
||||
path);
|
||||
gtk_css_parser_error (scanner->parser,
|
||||
GTK_CSS_PARSER_ERROR_IMPORT,
|
||||
gtk_css_parser_get_block_location (scanner->parser),
|
||||
gtk_css_parser_get_end_location (scanner->parser),
|
||||
"Loading '%s' would recurse",
|
||||
path);
|
||||
g_free (path);
|
||||
}
|
||||
else
|
||||
@@ -832,10 +727,7 @@ parse_import (GtkCssScanner *scanner)
|
||||
NULL);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_IMPORT);
|
||||
_gtk_css_parser_skip_whitespace (scanner->parser);
|
||||
g_clear_object (&file);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -847,54 +739,31 @@ parse_color_definition (GtkCssScanner *scanner)
|
||||
GtkCssValue *color;
|
||||
char *name;
|
||||
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
|
||||
if (!gtk_css_parser_try_at_keyword (scanner->parser, "define-color"))
|
||||
return FALSE;
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, "@define-color", TRUE))
|
||||
{
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
name = _gtk_css_parser_try_name (scanner->parser, TRUE);
|
||||
name = gtk_css_parser_consume_ident (scanner->parser);
|
||||
if (name == NULL)
|
||||
{
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"Not a valid color name");
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, 0);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
color = _gtk_css_color_value_parse (scanner->parser);
|
||||
if (color == NULL)
|
||||
{
|
||||
g_free (name);
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, 0);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, ";", TRUE))
|
||||
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
g_free (name);
|
||||
_gtk_css_value_unref (color);
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"Missing semicolon at end of color definition");
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, 0);
|
||||
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
|
||||
gtk_css_parser_error_syntax (scanner->parser,
|
||||
"Missing semicolon at end of color definition");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_hash_table_insert (priv->symbolic_colors, name, color);
|
||||
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -905,61 +774,27 @@ parse_keyframes (GtkCssScanner *scanner)
|
||||
GtkCssKeyframes *keyframes;
|
||||
char *name;
|
||||
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_KEYFRAMES);
|
||||
if (!gtk_css_parser_try_at_keyword (scanner->parser, "keyframes"))
|
||||
return FALSE;
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, "@keyframes", TRUE))
|
||||
name = gtk_css_parser_consume_ident (scanner->parser);
|
||||
if (name == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_KEYFRAMES);
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Expected '{' for keyframes");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
name = _gtk_css_parser_try_ident (scanner->parser, TRUE);
|
||||
if (name == NULL)
|
||||
{
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"Expected name for keyframes");
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, 0);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, "{", TRUE))
|
||||
{
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"Expected '{' for keyframes");
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, 0);
|
||||
g_free (name);
|
||||
goto exit;
|
||||
}
|
||||
gtk_css_parser_end_block_prelude (scanner->parser);
|
||||
|
||||
keyframes = _gtk_css_keyframes_parse (scanner->parser);
|
||||
if (keyframes == NULL)
|
||||
{
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
|
||||
g_free (name);
|
||||
goto exit;
|
||||
}
|
||||
if (keyframes != NULL)
|
||||
g_hash_table_insert (priv->keyframes, name, keyframes);
|
||||
|
||||
g_hash_table_insert (priv->keyframes, name, keyframes);
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, "}", TRUE))
|
||||
{
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"expected '}' after declarations");
|
||||
if (!_gtk_css_parser_is_eof (scanner->parser))
|
||||
_gtk_css_parser_resync (scanner->parser, FALSE, 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_KEYFRAMES);
|
||||
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Expected '}' after declarations");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -967,22 +802,16 @@ exit:
|
||||
static void
|
||||
parse_at_keyword (GtkCssScanner *scanner)
|
||||
{
|
||||
if (parse_import (scanner))
|
||||
return;
|
||||
if (parse_color_definition (scanner))
|
||||
return;
|
||||
if (parse_keyframes (scanner))
|
||||
return;
|
||||
gtk_css_parser_start_semicolon_block (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
|
||||
else
|
||||
if (!parse_import (scanner) &&
|
||||
!parse_color_definition (scanner) &&
|
||||
!parse_keyframes (scanner))
|
||||
{
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"unknown @ rule");
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, 0);
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Unknown @ rule");
|
||||
}
|
||||
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
}
|
||||
|
||||
static GSList *
|
||||
@@ -990,24 +819,15 @@ parse_selector_list (GtkCssScanner *scanner)
|
||||
{
|
||||
GSList *selectors = NULL;
|
||||
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_SELECTOR);
|
||||
|
||||
do {
|
||||
GtkCssSelector *select = _gtk_css_selector_parse (scanner->parser);
|
||||
|
||||
if (select == NULL)
|
||||
{
|
||||
g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
|
||||
_gtk_css_parser_resync (scanner->parser, FALSE, 0);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_SELECTOR);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
selectors = g_slist_prepend (selectors, select);
|
||||
}
|
||||
while (_gtk_css_parser_try (scanner->parser, ",", TRUE));
|
||||
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_SELECTOR);
|
||||
while (gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
return selectors;
|
||||
}
|
||||
@@ -1019,57 +839,64 @@ parse_declaration (GtkCssScanner *scanner,
|
||||
GtkStyleProperty *property;
|
||||
char *name;
|
||||
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_DECLARATION);
|
||||
/* advance the location over whitespace */
|
||||
gtk_css_parser_get_token (scanner->parser);
|
||||
gtk_css_parser_start_semicolon_block (scanner->parser, GTK_CSS_TOKEN_EOF);
|
||||
|
||||
name = _gtk_css_parser_try_ident (scanner->parser, TRUE);
|
||||
if (name == NULL)
|
||||
goto check_for_semicolon;
|
||||
|
||||
property = _gtk_style_property_lookup (name);
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, ":", TRUE))
|
||||
if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_provider_invalid_token (scanner->provider, scanner, "':'");
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
|
||||
g_free (name);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
|
||||
gtk_css_parser_warn_syntax (scanner->parser, "Empty declaration");
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
}
|
||||
|
||||
name = gtk_css_parser_consume_ident (scanner->parser);
|
||||
if (name == NULL)
|
||||
{
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
}
|
||||
|
||||
property = _gtk_style_property_lookup (name);
|
||||
|
||||
if (property)
|
||||
{
|
||||
GtkCssSection *section;
|
||||
GtkCssValue *value;
|
||||
|
||||
g_free (name);
|
||||
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_VALUE);
|
||||
if (!gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Expected ':'");
|
||||
g_free (name);
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
}
|
||||
|
||||
value = _gtk_style_property_parse_value (property,
|
||||
scanner->parser);
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_begins_with (scanner->parser, ';') &&
|
||||
!_gtk_css_parser_begins_with (scanner->parser, '}') &&
|
||||
!_gtk_css_parser_is_eof (scanner->parser))
|
||||
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_provider_error (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"Junk at end of value for %s", property->name);
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Junk at end of value for %s", property->name);
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gtk_keep_css_sections)
|
||||
{
|
||||
section = gtk_css_section_new (gtk_css_parser_get_file (scanner->parser),
|
||||
gtk_css_parser_get_block_location (scanner->parser),
|
||||
gtk_css_parser_get_end_location (scanner->parser));
|
||||
}
|
||||
else
|
||||
section = NULL;
|
||||
|
||||
if (GTK_IS_CSS_SHORTHAND_PROPERTY (property))
|
||||
{
|
||||
GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
|
||||
@@ -1080,14 +907,15 @@ parse_declaration (GtkCssScanner *scanner,
|
||||
GtkCssStyleProperty *child = _gtk_css_shorthand_property_get_subproperty (shorthand, i);
|
||||
GtkCssValue *sub = _gtk_css_array_value_get_nth (value, i);
|
||||
|
||||
gtk_css_ruleset_add (ruleset, child, _gtk_css_value_ref (sub), scanner->section);
|
||||
gtk_css_ruleset_add (ruleset, child, _gtk_css_value_ref (sub), section);
|
||||
}
|
||||
|
||||
_gtk_css_value_unref (value);
|
||||
}
|
||||
else if (GTK_IS_CSS_STYLE_PROPERTY (property))
|
||||
{
|
||||
gtk_css_ruleset_add (ruleset, GTK_CSS_STYLE_PROPERTY (property), value, scanner->section);
|
||||
|
||||
gtk_css_ruleset_add (ruleset, GTK_CSS_STYLE_PROPERTY (property), value, section);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1095,36 +923,23 @@ parse_declaration (GtkCssScanner *scanner,
|
||||
_gtk_css_value_unref (value);
|
||||
}
|
||||
|
||||
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
|
||||
g_clear_pointer (§ion, gtk_css_section_unref);
|
||||
}
|
||||
else
|
||||
g_free (name);
|
||||
|
||||
check_for_semicolon:
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, ";", TRUE))
|
||||
{
|
||||
if (!_gtk_css_parser_begins_with (scanner->parser, '}') &&
|
||||
!_gtk_css_parser_is_eof (scanner->parser))
|
||||
{
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"Expected semicolon");
|
||||
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
|
||||
}
|
||||
gtk_css_parser_error_value (scanner->parser, "No property named \"%s\"", name);
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_declarations (GtkCssScanner *scanner,
|
||||
GtkCssRuleset *ruleset)
|
||||
{
|
||||
while (!_gtk_css_parser_is_eof (scanner->parser) &&
|
||||
!_gtk_css_parser_begins_with (scanner->parser, '}'))
|
||||
while (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
parse_declaration (scanner, ruleset);
|
||||
}
|
||||
@@ -1136,55 +951,37 @@ parse_ruleset (GtkCssScanner *scanner)
|
||||
GSList *selectors;
|
||||
GtkCssRuleset ruleset = { 0, };
|
||||
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_RULESET);
|
||||
|
||||
selectors = parse_selector_list (scanner);
|
||||
if (selectors == NULL)
|
||||
{
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_RULESET);
|
||||
gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
gtk_css_parser_skip (scanner->parser);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, "{", TRUE))
|
||||
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY))
|
||||
{
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"expected '{' after selectors");
|
||||
_gtk_css_parser_resync (scanner->parser, FALSE, 0);
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Expected '{' after selectors");
|
||||
g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_RULESET);
|
||||
gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
gtk_css_parser_skip (scanner->parser);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_css_parser_start_block (scanner->parser);
|
||||
|
||||
parse_declarations (scanner, &ruleset);
|
||||
|
||||
if (!_gtk_css_parser_try (scanner->parser, "}", TRUE))
|
||||
{
|
||||
gtk_css_provider_error_literal (scanner->provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
"expected '}' after declarations");
|
||||
if (!_gtk_css_parser_is_eof (scanner->parser))
|
||||
{
|
||||
_gtk_css_parser_resync (scanner->parser, FALSE, 0);
|
||||
g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
|
||||
gtk_css_ruleset_clear (&ruleset);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_RULESET);
|
||||
}
|
||||
}
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
|
||||
css_provider_commit (scanner->provider, selectors, &ruleset);
|
||||
gtk_css_ruleset_clear (&ruleset);
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_RULESET);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_statement (GtkCssScanner *scanner)
|
||||
{
|
||||
if (_gtk_css_parser_begins_with (scanner->parser, '@'))
|
||||
if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_AT_KEYWORD))
|
||||
parse_at_keyword (scanner);
|
||||
else
|
||||
parse_ruleset (scanner);
|
||||
@@ -1193,20 +990,17 @@ parse_statement (GtkCssScanner *scanner)
|
||||
static void
|
||||
parse_stylesheet (GtkCssScanner *scanner)
|
||||
{
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_DOCUMENT);
|
||||
|
||||
_gtk_css_parser_skip_whitespace (scanner->parser);
|
||||
|
||||
while (!_gtk_css_parser_is_eof (scanner->parser))
|
||||
while (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
if (_gtk_css_parser_try (scanner->parser, "<!--", TRUE) ||
|
||||
_gtk_css_parser_try (scanner->parser, "-->", TRUE))
|
||||
continue;
|
||||
if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_CDO) ||
|
||||
gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_CDC))
|
||||
{
|
||||
gtk_css_parser_consume_token (scanner->parser);
|
||||
continue;
|
||||
}
|
||||
|
||||
parse_statement (scanner);
|
||||
}
|
||||
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DOCUMENT);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1263,77 +1057,55 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_provider_load_internal (GtkCssProvider *css_provider,
|
||||
gtk_css_provider_load_internal (GtkCssProvider *self,
|
||||
GtkCssScanner *parent,
|
||||
GFile *file,
|
||||
const char *text)
|
||||
GBytes *bytes)
|
||||
{
|
||||
GtkCssScanner *scanner;
|
||||
GBytes *bytes;
|
||||
|
||||
if (text == NULL)
|
||||
if (bytes == NULL)
|
||||
{
|
||||
GError *load_error = NULL;
|
||||
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, &load_error);
|
||||
|
||||
if (bytes)
|
||||
{
|
||||
text = g_bytes_get_data (bytes, NULL);
|
||||
}
|
||||
else
|
||||
if (bytes == NULL)
|
||||
{
|
||||
if (parent == NULL)
|
||||
{
|
||||
scanner = gtk_css_scanner_new (css_provider,
|
||||
NULL,
|
||||
NULL,
|
||||
file,
|
||||
"");
|
||||
GtkCssLocation empty = { 0, };
|
||||
GtkCssSection *section = gtk_css_section_new (file, &empty, &empty);
|
||||
|
||||
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_DOCUMENT);
|
||||
gtk_css_style_provider_emit_error (GTK_STYLE_PROVIDER (self), section, load_error);
|
||||
gtk_css_section_unref (section);
|
||||
}
|
||||
else
|
||||
scanner = parent;
|
||||
|
||||
gtk_css_provider_error (css_provider,
|
||||
scanner,
|
||||
GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_IMPORT,
|
||||
"Failed to import: %s",
|
||||
load_error->message);
|
||||
|
||||
if (parent == NULL)
|
||||
{
|
||||
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DOCUMENT);
|
||||
|
||||
gtk_css_scanner_destroy (scanner);
|
||||
gtk_css_parser_error (parent->parser,
|
||||
GTK_CSS_PARSER_ERROR_IMPORT,
|
||||
gtk_css_parser_get_block_location (parent->parser),
|
||||
gtk_css_parser_get_end_location (parent->parser),
|
||||
"Failed to import: %s",
|
||||
load_error->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = NULL;
|
||||
}
|
||||
|
||||
if (text)
|
||||
if (bytes)
|
||||
{
|
||||
scanner = gtk_css_scanner_new (css_provider,
|
||||
GtkCssScanner *scanner;
|
||||
|
||||
scanner = gtk_css_scanner_new (self,
|
||||
parent,
|
||||
parent ? parent->section : NULL,
|
||||
file,
|
||||
text);
|
||||
bytes);
|
||||
|
||||
parse_stylesheet (scanner);
|
||||
|
||||
gtk_css_scanner_destroy (scanner);
|
||||
|
||||
if (parent == NULL)
|
||||
gtk_css_provider_postprocess (css_provider);
|
||||
gtk_css_provider_postprocess (self);
|
||||
}
|
||||
|
||||
if (bytes)
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1352,27 +1124,21 @@ gtk_css_provider_load_from_data (GtkCssProvider *css_provider,
|
||||
const gchar *data,
|
||||
gssize length)
|
||||
{
|
||||
char *free_data;
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_PROVIDER (css_provider));
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
length = strlen (data);
|
||||
free_data = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
free_data = g_strndup (data, length);
|
||||
data = free_data;
|
||||
}
|
||||
length = strlen (data);
|
||||
|
||||
bytes = g_bytes_new_static (data, length);
|
||||
|
||||
gtk_css_provider_reset (css_provider);
|
||||
|
||||
gtk_css_provider_load_internal (css_provider, NULL, NULL, data);
|
||||
gtk_css_provider_load_internal (css_provider, NULL, NULL, bytes);
|
||||
|
||||
g_free (free_data);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
gtk_style_provider_changed (GTK_STYLE_PROVIDER (css_provider));
|
||||
}
|
||||
|
||||
+1
-32
@@ -19,7 +19,7 @@
|
||||
#define __GTK_CSS_PROVIDER_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtkcsssection.h>
|
||||
#include <gtk/css/gtkcss.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -30,37 +30,6 @@ G_BEGIN_DECLS
|
||||
#define GTK_IS_CSS_PROVIDER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GTK_TYPE_CSS_PROVIDER))
|
||||
#define GTK_CSS_PROVIDER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_CSS_PROVIDER, GtkCssProviderClass))
|
||||
|
||||
/**
|
||||
* GTK_CSS_PROVIDER_ERROR:
|
||||
*
|
||||
* Domain for #GtkCssProvider errors.
|
||||
*/
|
||||
#define GTK_CSS_PROVIDER_ERROR (gtk_css_provider_error_quark ())
|
||||
|
||||
/**
|
||||
* GtkCssProviderError:
|
||||
* @GTK_CSS_PROVIDER_ERROR_FAILED: Failed.
|
||||
* @GTK_CSS_PROVIDER_ERROR_SYNTAX: Syntax error.
|
||||
* @GTK_CSS_PROVIDER_ERROR_IMPORT: Import error.
|
||||
* @GTK_CSS_PROVIDER_ERROR_NAME: Name error.
|
||||
* @GTK_CSS_PROVIDER_ERROR_DEPRECATED: Deprecation error.
|
||||
* @GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE: Unknown value.
|
||||
*
|
||||
* Error codes for %GTK_CSS_PROVIDER_ERROR.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_PROVIDER_ERROR_FAILED,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
GTK_CSS_PROVIDER_ERROR_IMPORT,
|
||||
GTK_CSS_PROVIDER_ERROR_NAME,
|
||||
GTK_CSS_PROVIDER_ERROR_DEPRECATED,
|
||||
GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE
|
||||
} GtkCssProviderError;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GQuark gtk_css_provider_error_quark (void);
|
||||
|
||||
typedef struct _GtkCssProvider GtkCssProvider;
|
||||
typedef struct _GtkCssProviderClass GtkCssProviderClass;
|
||||
typedef struct _GtkCssProviderPrivate GtkCssProviderPrivate;
|
||||
|
||||
@@ -178,7 +178,7 @@ _gtk_css_background_repeat_style_try (GtkCssParser *parser,
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (background_repeat_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, background_repeat_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, background_repeat_values[i].name))
|
||||
{
|
||||
*result = i;
|
||||
return TRUE;
|
||||
@@ -195,9 +195,9 @@ _gtk_css_background_repeat_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
g_return_val_if_fail (parser != NULL, NULL);
|
||||
|
||||
if (_gtk_css_parser_try (parser, "repeat-x", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "repeat-x"))
|
||||
return _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
|
||||
if (_gtk_css_parser_try (parser, "repeat-y", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "repeat-y"))
|
||||
return _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT);
|
||||
|
||||
if (!_gtk_css_background_repeat_style_try (parser, &x))
|
||||
@@ -272,7 +272,7 @@ _gtk_css_border_repeat_style_try (GtkCssParser *parser,
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (border_repeat_values); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, border_repeat_values[i].name, TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, border_repeat_values[i].name))
|
||||
{
|
||||
*result = i;
|
||||
return TRUE;
|
||||
|
||||
@@ -1,321 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsssectionprivate.h"
|
||||
|
||||
#include "gtkcssparserprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
struct _GtkCssSection
|
||||
{
|
||||
gint ref_count;
|
||||
GtkCssSectionType section_type;
|
||||
GtkCssSection *parent;
|
||||
GFile *file;
|
||||
guint start_line;
|
||||
guint start_position;
|
||||
GtkCssParser *parser; /* parser if section isn't finished parsing yet or %NULL */
|
||||
guint end_line; /* end line if parser is %NULL */
|
||||
guint end_position; /* end position if parser is %NULL */
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GtkCssSection, gtk_css_section, gtk_css_section_ref, gtk_css_section_unref)
|
||||
|
||||
GtkCssSection *
|
||||
_gtk_css_section_new (GtkCssSection *parent,
|
||||
GtkCssSectionType type,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssSection *section;
|
||||
|
||||
gtk_internal_return_val_if_fail (parser != NULL, NULL);
|
||||
|
||||
section = g_slice_new0 (GtkCssSection);
|
||||
|
||||
section->ref_count = 1;
|
||||
section->section_type = type;
|
||||
if (parent)
|
||||
section->parent = gtk_css_section_ref (parent);
|
||||
section->file = _gtk_css_parser_get_file (parser);
|
||||
if (section->file)
|
||||
g_object_ref (section->file);
|
||||
section->start_line = _gtk_css_parser_get_line (parser);
|
||||
section->start_position = _gtk_css_parser_get_position (parser);
|
||||
section->parser = parser;
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
GtkCssSection *
|
||||
_gtk_css_section_new_for_file (GtkCssSectionType type,
|
||||
GFile *file)
|
||||
{
|
||||
GtkCssSection *section;
|
||||
|
||||
gtk_internal_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
|
||||
section = g_slice_new0 (GtkCssSection);
|
||||
|
||||
section->ref_count = 1;
|
||||
section->section_type = type;
|
||||
section->file = g_object_ref (file);
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_section_end (GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_if_fail (section != NULL);
|
||||
gtk_internal_return_if_fail (section->parser != NULL);
|
||||
|
||||
section->end_line = _gtk_css_parser_get_line (section->parser);
|
||||
section->end_position = _gtk_css_parser_get_position (section->parser);
|
||||
section->parser = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_ref:
|
||||
* @section: a #GtkCssSection
|
||||
*
|
||||
* Increments the reference count on @section.
|
||||
*
|
||||
* Returns: @section itself.
|
||||
**/
|
||||
GtkCssSection *
|
||||
gtk_css_section_ref (GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
section->ref_count += 1;
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_unref:
|
||||
* @section: a #GtkCssSection
|
||||
*
|
||||
* Decrements the reference count on @section, freeing the
|
||||
* structure if the reference count reaches 0.
|
||||
**/
|
||||
void
|
||||
gtk_css_section_unref (GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_if_fail (section != NULL);
|
||||
|
||||
section->ref_count -= 1;
|
||||
if (section->ref_count > 0)
|
||||
return;
|
||||
|
||||
if (section->parent)
|
||||
gtk_css_section_unref (section->parent);
|
||||
if (section->file)
|
||||
g_object_unref (section->file);
|
||||
|
||||
g_slice_free (GtkCssSection, section);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_section_type:
|
||||
* @section: the section
|
||||
*
|
||||
* Gets the type of information that @section describes.
|
||||
*
|
||||
* Returns: the type of @section
|
||||
**/
|
||||
GtkCssSectionType
|
||||
gtk_css_section_get_section_type (const GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (section != NULL, GTK_CSS_SECTION_DOCUMENT);
|
||||
|
||||
return section->section_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_parent:
|
||||
* @section: the section
|
||||
*
|
||||
* Gets the parent section for the given @section. The parent section is
|
||||
* the section that contains this @section. A special case are sections of
|
||||
* type #GTK_CSS_SECTION_DOCUMENT. Their parent will either be %NULL
|
||||
* if they are the original CSS document that was loaded by
|
||||
* gtk_css_provider_load_from_file() or a section of type
|
||||
* #GTK_CSS_SECTION_IMPORT if it was loaded with an import rule from
|
||||
* a different file.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the parent section or %NULL if none
|
||||
**/
|
||||
GtkCssSection *
|
||||
gtk_css_section_get_parent (const GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
return section->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_file:
|
||||
* @section: the section
|
||||
*
|
||||
* Gets the file that @section was parsed from. If no such file exists,
|
||||
* for example because the CSS was loaded via
|
||||
* @gtk_css_provider_load_from_data(), then %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer none): the #GFile that @section was parsed from
|
||||
* or %NULL if @section was parsed from other data
|
||||
**/
|
||||
GFile *
|
||||
gtk_css_section_get_file (const GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
return section->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_start_line:
|
||||
* @section: the section
|
||||
*
|
||||
* Returns the line in the CSS document where this section starts.
|
||||
* The line number is 0-indexed, so the first line of the document
|
||||
* will return 0.
|
||||
*
|
||||
* Returns: the line number
|
||||
**/
|
||||
guint
|
||||
gtk_css_section_get_start_line (const GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (section != NULL, 0);
|
||||
|
||||
return section->start_line;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_start_position:
|
||||
* @section: the section
|
||||
*
|
||||
* Returns the offset in bytes from the start of the current line
|
||||
* returned via gtk_css_section_get_start_line().
|
||||
*
|
||||
* Returns: the offset in bytes from the start of the line.
|
||||
**/
|
||||
guint
|
||||
gtk_css_section_get_start_position (const GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (section != NULL, 0);
|
||||
|
||||
return section->start_position;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_end_line:
|
||||
* @section: the section
|
||||
*
|
||||
* Returns the line in the CSS document where this section end.
|
||||
* The line number is 0-indexed, so the first line of the document
|
||||
* will return 0.
|
||||
* This value may change in future invocations of this function if
|
||||
* @section is not yet parsed completely. This will for example
|
||||
* happen in the GtkCssProvider::parsing-error signal.
|
||||
* The end position and line may be identical to the start
|
||||
* position and line for sections which failed to parse anything
|
||||
* successfully.
|
||||
*
|
||||
* Returns: the line number
|
||||
**/
|
||||
guint
|
||||
gtk_css_section_get_end_line (const GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (section != NULL, 0);
|
||||
|
||||
if (section->parser)
|
||||
return _gtk_css_parser_get_line (section->parser);
|
||||
else
|
||||
return section->end_line;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_section_get_end_position:
|
||||
* @section: the section
|
||||
*
|
||||
* Returns the offset in bytes from the start of the current line
|
||||
* returned via gtk_css_section_get_end_line().
|
||||
* This value may change in future invocations of this function if
|
||||
* @section is not yet parsed completely. This will for example
|
||||
* happen in the GtkCssProvider::parsing-error signal.
|
||||
* The end position and line may be identical to the start
|
||||
* position and line for sections which failed to parse anything
|
||||
* successfully.
|
||||
*
|
||||
* Returns: the offset in bytes from the start of the line.
|
||||
**/
|
||||
guint
|
||||
gtk_css_section_get_end_position (const GtkCssSection *section)
|
||||
{
|
||||
gtk_internal_return_val_if_fail (section != NULL, 0);
|
||||
|
||||
if (section->parser)
|
||||
return _gtk_css_parser_get_position (section->parser);
|
||||
else
|
||||
return section->end_position;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_section_print (const GtkCssSection *section,
|
||||
GString *string)
|
||||
{
|
||||
if (section->file)
|
||||
{
|
||||
GFileInfo *info;
|
||||
|
||||
info = g_file_query_info (section->file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0, NULL, NULL);
|
||||
|
||||
if (info)
|
||||
{
|
||||
g_string_append (string, g_file_info_get_display_name (info));
|
||||
g_object_unref (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append (string, "<broken file>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append (string, "<data>");
|
||||
}
|
||||
|
||||
g_string_append_printf (string, ":%u:%u",
|
||||
gtk_css_section_get_end_line (section) + 1,
|
||||
gtk_css_section_get_end_position (section));
|
||||
}
|
||||
|
||||
char *
|
||||
_gtk_css_section_to_string (const GtkCssSection *section)
|
||||
{
|
||||
GString *string;
|
||||
|
||||
gtk_internal_return_val_if_fail (section != NULL, NULL);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
_gtk_css_section_print (section, string);
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_SECTION_PRIVATE_H__
|
||||
#define __GTK_CSS_SECTION_PRIVATE_H__
|
||||
|
||||
#include "gtkcsssection.h"
|
||||
|
||||
#include "gtkcssparserprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkCssSection * _gtk_css_section_new (GtkCssSection *parent,
|
||||
GtkCssSectionType type,
|
||||
GtkCssParser *parser);
|
||||
GtkCssSection * _gtk_css_section_new_for_file (GtkCssSectionType type,
|
||||
GFile *file);
|
||||
|
||||
void _gtk_css_section_end (GtkCssSection *section);
|
||||
|
||||
void _gtk_css_section_print (const GtkCssSection *section,
|
||||
GString *string);
|
||||
char * _gtk_css_section_to_string (const GtkCssSection *section);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_SECTION_PRIVATE_H__ */
|
||||
+626
-302
@@ -25,6 +25,7 @@
|
||||
#include "gtkcssprovider.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
|
||||
#include <errno.h>
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1500
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
@@ -922,337 +923,621 @@ gtk_css_selector_new (const GtkCssSelectorClass *class,
|
||||
}
|
||||
|
||||
static GtkCssSelector *
|
||||
parse_selector_class (GtkCssParser *parser,
|
||||
GtkCssSelector *selector,
|
||||
gboolean negate)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = _gtk_css_parser_try_name (parser, FALSE);
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a valid name for class");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_CLASS
|
||||
: >K_CSS_SELECTOR_CLASS,
|
||||
selector);
|
||||
selector->style_class.style_class = g_quark_from_string (name);
|
||||
|
||||
g_free (name);
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
static GtkCssSelector *
|
||||
parse_selector_id (GtkCssParser *parser,
|
||||
GtkCssSelector *selector,
|
||||
gboolean negate)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = _gtk_css_parser_try_name (parser, FALSE);
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a valid name for id");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_ID
|
||||
: >K_CSS_SELECTOR_ID,
|
||||
selector);
|
||||
selector->id.name = g_intern_string (name);
|
||||
|
||||
g_free (name);
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
static GtkCssSelector *
|
||||
parse_selector_pseudo_class_nth_child (GtkCssParser *parser,
|
||||
gtk_css_selector_parse_selector_class (GtkCssParser *parser,
|
||||
GtkCssSelector *selector,
|
||||
PositionType type,
|
||||
gboolean negate)
|
||||
{
|
||||
int a, b;
|
||||
const GtkCssToken *token;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
gtk_css_parser_consume_token (parser);
|
||||
for (token = gtk_css_parser_peek_token (parser);
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_COMMENT);
|
||||
token = gtk_css_parser_peek_token (parser))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing opening bracket for pseudo-class");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, "even", TRUE))
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
a = 2;
|
||||
b = 0;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "odd", TRUE))
|
||||
{
|
||||
a = 2;
|
||||
b = 1;
|
||||
}
|
||||
else if (type == POSITION_FORWARD &&
|
||||
_gtk_css_parser_try (parser, "first", TRUE))
|
||||
{
|
||||
a = 0;
|
||||
b = 1;
|
||||
}
|
||||
else if (type == POSITION_FORWARD &&
|
||||
_gtk_css_parser_try (parser, "last", TRUE))
|
||||
{
|
||||
a = 0;
|
||||
b = 1;
|
||||
type = POSITION_BACKWARD;
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_CLASS
|
||||
: >K_CSS_SELECTOR_CLASS,
|
||||
selector);
|
||||
selector->style_class.style_class = g_quark_from_string (token->string.string);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return selector;
|
||||
}
|
||||
else
|
||||
{
|
||||
int multiplier;
|
||||
gtk_css_parser_error_syntax (parser, "No class name after '.' in selector");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, "+", TRUE))
|
||||
multiplier = 1;
|
||||
else if (_gtk_css_parser_try (parser, "-", TRUE))
|
||||
multiplier = -1;
|
||||
else
|
||||
multiplier = 1;
|
||||
static gboolean
|
||||
string_has_number (const char *string,
|
||||
const char *prefix,
|
||||
int *number)
|
||||
{
|
||||
gsize len = strlen (prefix);
|
||||
char *end;
|
||||
|
||||
if (_gtk_css_parser_try_int (parser, &a))
|
||||
if (g_ascii_strncasecmp (string, prefix, len) != 0)
|
||||
return FALSE;
|
||||
|
||||
errno = 0;
|
||||
*number = strtoul (string + len, &end, 10);
|
||||
if (*end != '\0' || errno != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_plus_b (GtkCssParser *parser,
|
||||
gboolean negate,
|
||||
gint *b)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
gboolean has_seen_sign;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (negate)
|
||||
{
|
||||
has_seen_sign = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_css_token_is_delim (token, '+'))
|
||||
{
|
||||
if (a < 0)
|
||||
gtk_css_parser_consume_token (parser);
|
||||
has_seen_sign = TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '-'))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
negate = TRUE;
|
||||
has_seen_sign = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
has_seen_sign = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (!has_seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER))
|
||||
{
|
||||
*b = token->number.number;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (has_seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER))
|
||||
{
|
||||
*b = token->number.number;
|
||||
if (negate)
|
||||
*b = - *b;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (!has_seen_sign)
|
||||
{
|
||||
*b = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid an+b type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_n_plus_b (GtkCssParser *parser,
|
||||
gint before,
|
||||
gint *a,
|
||||
gint *b)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (gtk_css_token_is_ident (token, "n"))
|
||||
{
|
||||
*a = before;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return parse_plus_b (parser, FALSE, b);
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "n-"))
|
||||
{
|
||||
*a = before;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return parse_plus_b (parser, TRUE, b);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
string_has_number (token->string.string, "n-", b))
|
||||
{
|
||||
*a = before;
|
||||
*b = -*b;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*b = before;
|
||||
*a = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid an+b type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_a_n_plus_b (GtkCssParser *parser,
|
||||
gint seen_sign,
|
||||
gint *a,
|
||||
gint *b)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (!seen_sign && gtk_css_token_is_ident (token, "even"))
|
||||
{
|
||||
*a = 2;
|
||||
*b = 0;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (!seen_sign && gtk_css_token_is_ident (token, "odd"))
|
||||
{
|
||||
*a = 2;
|
||||
*b = 1;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (!seen_sign && gtk_css_token_is_delim (token, '+'))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return parse_a_n_plus_b (parser, 1, a, b);
|
||||
}
|
||||
else if (!seen_sign && gtk_css_token_is_delim (token, '-'))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return parse_a_n_plus_b (parser, -1, a, b);
|
||||
}
|
||||
else if ((!seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER)) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER))
|
||||
{
|
||||
int x = token->number.number * (seen_sign ? seen_sign : 1);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
|
||||
return parse_n_plus_b (parser, x , a, b);
|
||||
}
|
||||
else if (((!seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION)) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION)) &&
|
||||
g_ascii_strcasecmp (token->dimension.dimension, "n") == 0)
|
||||
{
|
||||
*a = token->dimension.value * (seen_sign ? seen_sign : 1);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return parse_plus_b (parser, FALSE, b);
|
||||
}
|
||||
else if (((!seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION)) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION)) &&
|
||||
g_ascii_strcasecmp (token->dimension.dimension, "n-") == 0)
|
||||
{
|
||||
*a = token->dimension.value * (seen_sign ? seen_sign : 1);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return parse_plus_b (parser, TRUE, b);
|
||||
}
|
||||
else if (((!seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION)) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION)) &&
|
||||
string_has_number (token->dimension.dimension, "n-", b))
|
||||
{
|
||||
*a = token->dimension.value * (seen_sign ? seen_sign : 1);
|
||||
*b = -*b;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (!seen_sign && gtk_css_token_is_ident (token, "-n"))
|
||||
{
|
||||
*a = -1;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return parse_plus_b (parser, FALSE, b);
|
||||
}
|
||||
else if (!seen_sign && gtk_css_token_is_ident (token, "-n-"))
|
||||
{
|
||||
*a = -1;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return parse_plus_b (parser, TRUE, b);
|
||||
}
|
||||
else if (!seen_sign &&
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
string_has_number (token->string.string, "-n-", b))
|
||||
{
|
||||
*a = -1;
|
||||
*b = -*b;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "n") ||
|
||||
gtk_css_token_is_ident (token, "n-"))
|
||||
{
|
||||
return parse_n_plus_b (parser, seen_sign ? seen_sign : 1, a, b);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
string_has_number (token->string.string, "n-", b))
|
||||
{
|
||||
*a = seen_sign ? seen_sign : 1;
|
||||
*b = -*b;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
else if (!seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
string_has_number (token->string.string, "-n-", b))
|
||||
{
|
||||
*a = -1;
|
||||
*b = -*b;
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid an+b type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_a_n_plus_b_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
gint *ab = data;
|
||||
|
||||
if (!parse_a_n_plus_b (parser, FALSE, &ab[0], &ab[1]))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_dir_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GtkStateFlags *flag = data;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "ltr"))
|
||||
{
|
||||
*flag = GTK_STATE_FLAG_DIR_LTR;
|
||||
return 1;
|
||||
}
|
||||
else if (gtk_css_parser_try_ident (parser, "rtl"))
|
||||
{
|
||||
*flag = GTK_STATE_FLAG_DIR_RTL;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Expected \"ltr\" or \"rtl\"");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_identifier_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
const char *ident = data;
|
||||
|
||||
if (!gtk_css_parser_try_ident (parser, ident))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Expected \"%s\"", ident);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static GtkCssSelector *
|
||||
gtk_css_selector_parse_selector_pseudo_class (GtkCssParser *parser,
|
||||
GtkCssSelector *selector,
|
||||
gboolean negate)
|
||||
{
|
||||
GtkCssLocation start_location;
|
||||
const GtkCssToken *token;
|
||||
|
||||
start_location = *gtk_css_parser_get_start_location (parser);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
for (token = gtk_css_parser_peek_token (parser);
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_COMMENT);
|
||||
token = gtk_css_parser_peek_token (parser))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
GtkStateFlags state_flag;
|
||||
PositionType position_type;
|
||||
int position_a;
|
||||
int position_b;
|
||||
} pseudo_classes[] = {
|
||||
{ "first-child", 0, POSITION_FORWARD, 0, 1 },
|
||||
{ "last-child", 0, POSITION_BACKWARD, 0, 1 },
|
||||
{ "only-child", 0, POSITION_ONLY, 0, 0 },
|
||||
{ "active", GTK_STATE_FLAG_ACTIVE, },
|
||||
{ "hover", GTK_STATE_FLAG_PRELIGHT, },
|
||||
{ "selected", GTK_STATE_FLAG_SELECTED, },
|
||||
{ "disabled", GTK_STATE_FLAG_INSENSITIVE, },
|
||||
{ "indeterminate", GTK_STATE_FLAG_INCONSISTENT, },
|
||||
{ "focus", GTK_STATE_FLAG_FOCUSED, },
|
||||
{ "backdrop", GTK_STATE_FLAG_BACKDROP, },
|
||||
{ "link", GTK_STATE_FLAG_LINK, },
|
||||
{ "visited", GTK_STATE_FLAG_VISITED, },
|
||||
{ "checked", GTK_STATE_FLAG_CHECKED, },
|
||||
};
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pseudo_classes); i++)
|
||||
{
|
||||
if (g_ascii_strcasecmp (pseudo_classes[i].name, token->string.string) == 0)
|
||||
{
|
||||
if (pseudo_classes[i].state_flag)
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = pseudo_classes[i].state_flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_POSITION
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector);
|
||||
selector->position.type = pseudo_classes[i].position_type;
|
||||
selector->position.a = pseudo_classes[i].position_a;
|
||||
selector->position.b = pseudo_classes[i].position_b;
|
||||
}
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return selector;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
"Unknown name of pseudo-class");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION))
|
||||
{
|
||||
if (gtk_css_token_is_function (token, "nth-child"))
|
||||
{
|
||||
gint ab[2];
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, parse_a_n_plus_b_arg, ab))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected an integer");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
a *= multiplier;
|
||||
}
|
||||
else if (_gtk_css_parser_has_prefix (parser, "n"))
|
||||
{
|
||||
a = multiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected an integer");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, "n", TRUE))
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_POSITION
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector);
|
||||
selector->position.type = POSITION_FORWARD;
|
||||
selector->position.a = ab[0];
|
||||
selector->position.b = ab[1];
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "nth-last-child"))
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "+", TRUE))
|
||||
multiplier = 1;
|
||||
else if (_gtk_css_parser_try (parser, "-", TRUE))
|
||||
multiplier = -1;
|
||||
else
|
||||
multiplier = 1;
|
||||
gint ab[2];
|
||||
|
||||
if (_gtk_css_parser_try_int (parser, &b))
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, parse_a_n_plus_b_arg, ab))
|
||||
{
|
||||
if (b < 0)
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_POSITION
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector);
|
||||
selector->position.type = POSITION_BACKWARD;
|
||||
selector->position.a = ab[0];
|
||||
selector->position.b = ab[1];
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "not"))
|
||||
{
|
||||
if (negate)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Nesting of :not() not allowed");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_start_block (parser);
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (gtk_css_token_is_delim (token, '*'))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected an integer");
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_ANY, selector);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_NAME, selector);
|
||||
selector->name.name = g_intern_string (token->string.string);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_ID, selector);
|
||||
selector->id.name = g_intern_string (token->string.string);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '.'))
|
||||
{
|
||||
selector = gtk_css_selector_parse_selector_class (parser, selector, TRUE);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
selector = gtk_css_selector_parse_selector_pseudo_class (parser, selector, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Invalid contents of :not() selector");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
selector = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
b = 0;
|
||||
|
||||
b *= multiplier;
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Invalid contents of :not() selector");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
selector = NULL;
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_parser_end_block (parser);
|
||||
}
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "dir"))
|
||||
{
|
||||
GtkStateFlags flag;
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, parse_dir_arg, &flag))
|
||||
{
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = flag;
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "drop"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, parse_identifier_arg, (gpointer) "active"))
|
||||
{
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = GTK_STATE_FLAG_DROP_ACTIVE;
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "focus"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, parse_identifier_arg, (gpointer) "visible"))
|
||||
{
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = GTK_STATE_FLAG_FOCUS_VISIBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = a;
|
||||
a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", FALSE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing bracket for pseudo-class");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_POSITION
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector);
|
||||
selector->position.type = type;
|
||||
selector->position.a = a;
|
||||
selector->position.b = b;
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
static GtkCssSelector *
|
||||
parse_selector_pseudo_class (GtkCssParser *parser,
|
||||
GtkCssSelector *selector,
|
||||
gboolean negate)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
GtkStateFlags state_flag;
|
||||
PositionType position_type;
|
||||
int position_a;
|
||||
int position_b;
|
||||
} pseudo_classes[] = {
|
||||
{ "first-child", 0, POSITION_FORWARD, 0, 1 },
|
||||
{ "last-child", 0, POSITION_BACKWARD, 0, 1 },
|
||||
{ "only-child", 0, POSITION_ONLY, 0, 0 },
|
||||
{ "active", GTK_STATE_FLAG_ACTIVE, },
|
||||
{ "hover", GTK_STATE_FLAG_PRELIGHT, },
|
||||
{ "selected", GTK_STATE_FLAG_SELECTED, },
|
||||
{ "disabled", GTK_STATE_FLAG_INSENSITIVE, },
|
||||
{ "indeterminate", GTK_STATE_FLAG_INCONSISTENT, },
|
||||
{ "focus(visible)", GTK_STATE_FLAG_FOCUS_VISIBLE, },
|
||||
{ "focus", GTK_STATE_FLAG_FOCUSED, },
|
||||
{ "backdrop", GTK_STATE_FLAG_BACKDROP, },
|
||||
{ "dir(ltr)", GTK_STATE_FLAG_DIR_LTR, },
|
||||
{ "dir(rtl)", GTK_STATE_FLAG_DIR_RTL, },
|
||||
{ "link", GTK_STATE_FLAG_LINK, },
|
||||
{ "visited", GTK_STATE_FLAG_VISITED, },
|
||||
{ "checked", GTK_STATE_FLAG_CHECKED, },
|
||||
{ "drop(active)", GTK_STATE_FLAG_DROP_ACTIVE, }
|
||||
};
|
||||
|
||||
guint i;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "nth-child", FALSE))
|
||||
return parse_selector_pseudo_class_nth_child (parser, selector, POSITION_FORWARD, negate);
|
||||
else if (_gtk_css_parser_try (parser, "nth-last-child", FALSE))
|
||||
return parse_selector_pseudo_class_nth_child (parser, selector, POSITION_BACKWARD, negate);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pseudo_classes); i++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, pseudo_classes[i].name, FALSE))
|
||||
{
|
||||
if (pseudo_classes[i].state_flag)
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = pseudo_classes[i].state_flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_POSITION
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector);
|
||||
selector->position.type = pseudo_classes[i].position_type;
|
||||
selector->position.a = pseudo_classes[i].position_a;
|
||||
selector->position.b = pseudo_classes[i].position_b;
|
||||
}
|
||||
return selector;
|
||||
}
|
||||
}
|
||||
|
||||
_gtk_css_parser_error (parser, "Invalid name of pseudo-class");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkCssSelector *
|
||||
parse_selector_negation (GtkCssParser *parser,
|
||||
GtkCssSelector *selector)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = _gtk_css_parser_try_ident (parser, FALSE);
|
||||
if (name)
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_NAME,
|
||||
selector);
|
||||
selector->name.name = g_intern_string (name);
|
||||
g_free (name);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "*", FALSE))
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_ANY, selector);
|
||||
else if (_gtk_css_parser_try (parser, "#", FALSE))
|
||||
selector = parse_selector_id (parser, selector, TRUE);
|
||||
else if (_gtk_css_parser_try (parser, ".", FALSE))
|
||||
selector = parse_selector_class (parser, selector, TRUE);
|
||||
else if (_gtk_css_parser_try (parser, ":", FALSE))
|
||||
selector = parse_selector_pseudo_class (parser, selector, TRUE);
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid selector for :not()");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", FALSE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing closing bracket for :not()");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
static GtkCssSelector *
|
||||
parse_simple_selector (GtkCssParser *parser,
|
||||
GtkCssSelector *selector)
|
||||
{
|
||||
gboolean parsed_something = FALSE;
|
||||
char *name;
|
||||
|
||||
name = _gtk_css_parser_try_ident (parser, FALSE);
|
||||
if (name)
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NAME, selector);
|
||||
selector->name.name = g_intern_string (name);
|
||||
g_free (name);
|
||||
parsed_something = TRUE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "*", FALSE))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ANY, selector);
|
||||
parsed_something = TRUE;
|
||||
}
|
||||
|
||||
do {
|
||||
if (_gtk_css_parser_try (parser, "#", FALSE))
|
||||
selector = parse_selector_id (parser, selector, FALSE);
|
||||
else if (_gtk_css_parser_try (parser, ".", FALSE))
|
||||
selector = parse_selector_class (parser, selector, FALSE);
|
||||
else if (_gtk_css_parser_try (parser, ":not(", TRUE))
|
||||
selector = parse_selector_negation (parser, selector);
|
||||
else if (_gtk_css_parser_try (parser, ":", FALSE))
|
||||
selector = parse_selector_pseudo_class (parser, selector, FALSE);
|
||||
else if (!parsed_something)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a valid selector");
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
"Unknown pseudoclass");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
"Unknown pseudoclass");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
static GtkCssSelector *
|
||||
gtk_css_selector_parse_simple_selector (GtkCssParser *parser,
|
||||
GtkCssSelector *selector)
|
||||
{
|
||||
gboolean parsed_something = FALSE;
|
||||
const GtkCssToken *token;
|
||||
|
||||
do {
|
||||
for (token = gtk_css_parser_peek_token (parser);
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_COMMENT);
|
||||
token = gtk_css_parser_peek_token (parser))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
|
||||
if (!parsed_something && gtk_css_token_is_delim (token, '*'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ANY, selector);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (!parsed_something && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NAME, selector);
|
||||
selector->name.name = g_intern_string (token->string.string);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ID, selector);
|
||||
selector->id.name = g_intern_string (token->string.string);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '.'))
|
||||
{
|
||||
selector = gtk_css_selector_parse_selector_class (parser, selector, FALSE);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
selector = gtk_css_selector_parse_selector_pseudo_class (parser, selector, FALSE);
|
||||
}
|
||||
else
|
||||
break;
|
||||
{
|
||||
if (!parsed_something)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid selector");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
selector = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
parsed_something = TRUE;
|
||||
}
|
||||
while (selector && !_gtk_css_parser_is_eof (parser));
|
||||
|
||||
_gtk_css_parser_skip_whitespace (parser);
|
||||
while (TRUE);
|
||||
|
||||
return selector;
|
||||
}
|
||||
@@ -1261,20 +1546,59 @@ GtkCssSelector *
|
||||
_gtk_css_selector_parse (GtkCssParser *parser)
|
||||
{
|
||||
GtkCssSelector *selector = NULL;
|
||||
const GtkCssToken *token;
|
||||
|
||||
while ((selector = parse_simple_selector (parser, selector)) &&
|
||||
!_gtk_css_parser_is_eof (parser) &&
|
||||
!_gtk_css_parser_begins_with (parser, ',') &&
|
||||
!_gtk_css_parser_begins_with (parser, '{'))
|
||||
while (TRUE)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "+", TRUE))
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ADJACENT, selector);
|
||||
else if (_gtk_css_parser_try (parser, "~", TRUE))
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_SIBLING, selector);
|
||||
else if (_gtk_css_parser_try (parser, ">", TRUE))
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_CHILD, selector);
|
||||
gboolean seen_whitespace = FALSE;
|
||||
|
||||
/* skip all whitespace and comments */
|
||||
gtk_css_parser_get_token (parser);
|
||||
|
||||
selector = gtk_css_selector_parse_simple_selector (parser, selector);
|
||||
if (selector == NULL)
|
||||
return NULL;
|
||||
|
||||
for (token = gtk_css_parser_peek_token (parser);
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_COMMENT) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_WHITESPACE);
|
||||
token = gtk_css_parser_peek_token (parser))
|
||||
{
|
||||
seen_whitespace |= gtk_css_token_is (token, GTK_CSS_TOKEN_WHITESPACE);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
|
||||
if (gtk_css_token_is_delim (token, '+'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ADJACENT, selector);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '~'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_SIBLING, selector);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '>'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_CHILD, selector);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_EOF) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_COMMA) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (seen_whitespace)
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_DESCENDANT, selector);
|
||||
}
|
||||
else
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_DESCENDANT, selector);
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid selector");
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return selector;
|
||||
|
||||
@@ -240,7 +240,7 @@ _gtk_css_shadows_value_parse (GtkCssParser *parser,
|
||||
GtkCssValue *value, *result;
|
||||
GPtrArray *values;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "none", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
return _gtk_css_shadows_value_new_none ();
|
||||
|
||||
values = g_ptr_array_new ();
|
||||
@@ -256,7 +256,7 @@ _gtk_css_shadows_value_parse (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
g_ptr_array_add (values, value);
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
result = gtk_css_shadows_value_new ((GtkCssValue **) values->pdata, values->len);
|
||||
g_ptr_array_free (values, TRUE);
|
||||
|
||||
+105
-82
@@ -201,109 +201,132 @@ _gtk_css_shadow_value_new_for_transition (GtkCssValue *target)
|
||||
_gtk_css_rgba_value_new_from_rgba (&transparent));
|
||||
}
|
||||
|
||||
enum {
|
||||
HOFFSET,
|
||||
VOFFSET,
|
||||
RADIUS,
|
||||
SPREAD,
|
||||
N_VALUES
|
||||
};
|
||||
|
||||
static gboolean
|
||||
value_is_done_parsing (GtkCssParser *parser)
|
||||
has_inset (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer box_shadow_mode)
|
||||
{
|
||||
return _gtk_css_parser_is_eof (parser) ||
|
||||
_gtk_css_parser_begins_with (parser, ',') ||
|
||||
_gtk_css_parser_begins_with (parser, ';') ||
|
||||
_gtk_css_parser_begins_with (parser, '}');
|
||||
return box_shadow_mode && gtk_css_parser_has_ident (parser, "inset");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_inset (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer box_shadow_mode)
|
||||
{
|
||||
gboolean *inset = option_data;
|
||||
|
||||
if (!gtk_css_parser_try_ident (parser, "inset"))
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*inset = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_lengths (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer box_shadow_mode)
|
||||
{
|
||||
GtkCssValue **values = option_data;
|
||||
|
||||
values[HOFFSET] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH);
|
||||
if (values[HOFFSET] == NULL)
|
||||
return FALSE;
|
||||
|
||||
values[VOFFSET] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH);
|
||||
if (values[VOFFSET] == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
values[RADIUS] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH
|
||||
| GTK_CSS_POSITIVE_ONLY);
|
||||
if (values[RADIUS] == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
values[RADIUS] = _gtk_css_number_value_new (0.0, GTK_CSS_PX);
|
||||
|
||||
if (box_shadow_mode && gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
values[SPREAD] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH);
|
||||
if (values[SPREAD] == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
values[SPREAD] = _gtk_css_number_value_new (0.0, GTK_CSS_PX);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer box_shadow_mode)
|
||||
{
|
||||
GtkCssValue **color = option_data;
|
||||
|
||||
*color = _gtk_css_color_value_parse (parser);
|
||||
if (*color == NULL)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_shadow_value_parse (GtkCssParser *parser,
|
||||
gboolean box_shadow_mode)
|
||||
{
|
||||
enum {
|
||||
HOFFSET,
|
||||
VOFFSET,
|
||||
RADIUS,
|
||||
SPREAD,
|
||||
COLOR,
|
||||
N_VALUES
|
||||
};
|
||||
GtkCssValue *values[N_VALUES] = { NULL, };
|
||||
gboolean inset;
|
||||
GtkCssValue *color = NULL;
|
||||
gboolean inset = FALSE;
|
||||
GtkCssParseOption options[] =
|
||||
{
|
||||
{ (void *) gtk_css_number_value_can_parse, parse_lengths, values },
|
||||
{ has_inset, parse_inset, &inset },
|
||||
{ (void *) gtk_css_color_value_can_parse, parse_color, &color },
|
||||
};
|
||||
guint i;
|
||||
|
||||
if (box_shadow_mode)
|
||||
inset = _gtk_css_parser_try (parser, "inset", TRUE);
|
||||
else
|
||||
inset = FALSE;
|
||||
if (!gtk_css_parser_consume_any (parser, options, G_N_ELEMENTS (options), GUINT_TO_POINTER (box_shadow_mode)))
|
||||
goto fail;
|
||||
|
||||
do
|
||||
{
|
||||
if (values[HOFFSET] == NULL &&
|
||||
gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
values[HOFFSET] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH);
|
||||
if (values[HOFFSET] == NULL)
|
||||
goto fail;
|
||||
if (values[0] == NULL)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected shadow value to contain a length");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
values[VOFFSET] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH);
|
||||
if (values[VOFFSET] == NULL)
|
||||
goto fail;
|
||||
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
values[RADIUS] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH
|
||||
| GTK_CSS_POSITIVE_ONLY);
|
||||
if (values[RADIUS] == NULL)
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
values[RADIUS] = _gtk_css_number_value_new (0.0, GTK_CSS_PX);
|
||||
|
||||
if (box_shadow_mode && gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
values[SPREAD] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH);
|
||||
if (values[SPREAD] == NULL)
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
values[SPREAD] = _gtk_css_number_value_new (0.0, GTK_CSS_PX);
|
||||
}
|
||||
else if (!inset && box_shadow_mode && _gtk_css_parser_try (parser, "inset", TRUE))
|
||||
{
|
||||
if (values[HOFFSET] == NULL)
|
||||
goto fail;
|
||||
inset = TRUE;
|
||||
break;
|
||||
}
|
||||
else if (values[COLOR] == NULL)
|
||||
{
|
||||
values[COLOR] = _gtk_css_color_value_parse (parser);
|
||||
|
||||
if (values[COLOR] == NULL)
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We parsed everything and there's still stuff left?
|
||||
* Pretend we didn't notice and let the normal code produce
|
||||
* a 'junk at end of value' error */
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
while (values[HOFFSET] == NULL || !value_is_done_parsing (parser));
|
||||
|
||||
if (values[COLOR] == NULL)
|
||||
values[COLOR] = _gtk_css_color_value_new_current_color ();
|
||||
if (color == NULL)
|
||||
color = _gtk_css_color_value_new_current_color ();
|
||||
|
||||
return gtk_css_shadow_value_new (values[HOFFSET], values[VOFFSET],
|
||||
values[RADIUS], values[SPREAD],
|
||||
inset, values[COLOR]);
|
||||
inset, color);
|
||||
|
||||
fail:
|
||||
for (i = 0; i < N_VALUES; i++)
|
||||
{
|
||||
if (values[i])
|
||||
_gtk_css_value_unref (values[i]);
|
||||
g_clear_pointer (&values[i], gtk_css_value_unref);
|
||||
}
|
||||
g_clear_pointer (&color, gtk_css_value_unref);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ gtk_css_shorthand_property_parse_value (GtkStyleProperty *property,
|
||||
|
||||
data = g_new0 (GtkCssValue *, shorthand->subproperties->len);
|
||||
|
||||
if (_gtk_css_parser_try (parser, "initial", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "initial"))
|
||||
{
|
||||
/* the initial value can be explicitly specified with the
|
||||
* ‘initial’ keyword which all properties accept.
|
||||
@@ -94,7 +94,7 @@ gtk_css_shorthand_property_parse_value (GtkStyleProperty *property,
|
||||
data[i] = _gtk_css_initial_value_new ();
|
||||
}
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "inherit", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "inherit"))
|
||||
{
|
||||
/* All properties accept the ‘inherit’ value which
|
||||
* explicitly specifies that the value will be determined
|
||||
@@ -107,7 +107,7 @@ gtk_css_shorthand_property_parse_value (GtkStyleProperty *property,
|
||||
data[i] = _gtk_css_inherit_value_new ();
|
||||
}
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "unset", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "unset"))
|
||||
{
|
||||
/* If the cascaded value of a property is the unset keyword,
|
||||
* then if it is an inherited property, this is treated as
|
||||
|
||||
@@ -50,10 +50,10 @@
|
||||
static gboolean
|
||||
value_is_done_parsing (GtkCssParser *parser)
|
||||
{
|
||||
return _gtk_css_parser_is_eof (parser) ||
|
||||
_gtk_css_parser_begins_with (parser, ',') ||
|
||||
_gtk_css_parser_begins_with (parser, ';') ||
|
||||
_gtk_css_parser_begins_with (parser, '}');
|
||||
return gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF) ||
|
||||
gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_COMMA) ||
|
||||
gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SEMICOLON) ||
|
||||
gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_CLOSE_CURLY);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -76,7 +76,7 @@ parse_four_numbers (GtkCssShorthandProperty *shorthand,
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a length");
|
||||
gtk_css_parser_error_syntax (parser, "Expected a length");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ parse_border_radius (GtkCssShorthandProperty *shorthand,
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a number");
|
||||
gtk_css_parser_error_syntax (parser, "Expected a number");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ parse_border_radius (GtkCssShorthandProperty *shorthand,
|
||||
for (; i < 4; i++)
|
||||
x[i] = _gtk_css_value_ref (x[(i - 1) >> 1]);
|
||||
|
||||
if (_gtk_css_parser_try (parser, "/", TRUE))
|
||||
if (gtk_css_parser_try_delim (parser, '/'))
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -171,7 +171,7 @@ parse_border_radius (GtkCssShorthandProperty *shorthand,
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a number");
|
||||
gtk_css_parser_error_syntax (parser, "Expected a number");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ parse_border_style (GtkCssShorthandProperty *shorthand,
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected a border style");
|
||||
gtk_css_parser_error_syntax (parser, "Expected a border style");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -261,12 +261,12 @@ parse_border_image (GtkCssShorthandProperty *shorthand,
|
||||
do
|
||||
{
|
||||
if (values[0] == NULL &&
|
||||
(_gtk_css_parser_has_prefix (parser, "none") ||
|
||||
(gtk_css_parser_has_ident (parser, "none") ||
|
||||
_gtk_css_image_can_parse (parser)))
|
||||
{
|
||||
GtkCssImage *image;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "none", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
image = NULL;
|
||||
else
|
||||
{
|
||||
@@ -293,7 +293,7 @@ parse_border_image (GtkCssShorthandProperty *shorthand,
|
||||
if (values[1] == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "/", TRUE))
|
||||
if (gtk_css_parser_try_delim (parser, '/'))
|
||||
{
|
||||
values[2] = _gtk_css_border_value_parse (parser,
|
||||
GTK_CSS_PARSE_PERCENT
|
||||
@@ -418,9 +418,9 @@ parse_border (GtkCssShorthandProperty *shorthand,
|
||||
static GtkCssValue *
|
||||
_gtk_css_font_variant_value_try_parse (GtkCssParser *parser)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "normal", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "normal"))
|
||||
return _gtk_css_ident_value_new ("normal");
|
||||
else if (_gtk_css_parser_try (parser, "small-caps", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "small-caps"))
|
||||
return _gtk_css_ident_value_new ("small-caps");
|
||||
return NULL;
|
||||
}
|
||||
@@ -450,7 +450,33 @@ parse_font (GtkCssShorthandProperty *shorthand,
|
||||
|
||||
if (values[3] == NULL)
|
||||
{
|
||||
values[3] = _gtk_css_font_weight_value_try_parse (parser);
|
||||
values[3] = gtk_css_font_weight_value_try_parse (parser);
|
||||
if (values[3] == NULL && gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
/* This needs to check for font-size, too */
|
||||
GtkCssValue *num = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_NUMBER |
|
||||
GTK_CSS_PARSE_LENGTH |
|
||||
GTK_CSS_PARSE_PERCENT |
|
||||
GTK_CSS_POSITIVE_ONLY);
|
||||
if (num == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (gtk_css_number_value_get_dimension (num) != GTK_CSS_DIMENSION_NUMBER)
|
||||
{
|
||||
values[5] = num;
|
||||
goto have_font_size;
|
||||
}
|
||||
|
||||
values[3] = num;
|
||||
if (_gtk_css_number_value_get (values[3], 100) < 1 ||
|
||||
_gtk_css_number_value_get (values[3], 100) > 1000)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Font weight values must be between 1 and 1000");
|
||||
g_clear_pointer (&values[3], gtk_css_value_unref);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
parsed_one = parsed_one || values[3] != NULL;
|
||||
}
|
||||
|
||||
@@ -463,10 +489,15 @@ parse_font (GtkCssShorthandProperty *shorthand,
|
||||
while (parsed_one && !value_is_done_parsing (parser));
|
||||
|
||||
values[5] = gtk_css_font_size_value_parse (parser);
|
||||
if (values[5] == NULL)
|
||||
return FALSE;
|
||||
|
||||
have_font_size:
|
||||
values[0] = gtk_css_font_family_value_parse (parser);
|
||||
if (values[0] == NULL)
|
||||
return FALSE;
|
||||
|
||||
return values[0] != NULL && values[5] != NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -480,12 +511,12 @@ parse_one_background (GtkCssShorthandProperty *shorthand,
|
||||
{
|
||||
/* the image part */
|
||||
if (values[0] == NULL &&
|
||||
(_gtk_css_parser_has_prefix (parser, "none") ||
|
||||
(gtk_css_parser_has_ident (parser, "none") ||
|
||||
_gtk_css_image_can_parse (parser)))
|
||||
{
|
||||
GtkCssImage *image;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "none", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
image = NULL;
|
||||
else
|
||||
{
|
||||
@@ -502,7 +533,7 @@ parse_one_background (GtkCssShorthandProperty *shorthand,
|
||||
values[1] = value;
|
||||
value = NULL;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "/", TRUE) &&
|
||||
if (gtk_css_parser_try_delim (parser, '/') &&
|
||||
(value = _gtk_css_bg_size_value_parse (parser)))
|
||||
{
|
||||
values[2] = value;
|
||||
@@ -595,7 +626,7 @@ parse_background (GtkCssShorthandProperty *shorthand,
|
||||
g_ptr_array_add (arrays[i], step_values[i]);
|
||||
step_values[i] = NULL;
|
||||
}
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
@@ -608,57 +639,64 @@ parse_background (GtkCssShorthandProperty *shorthand,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_transition_property (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer user_data)
|
||||
{
|
||||
return gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_transition_property (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssValue **value = option_data;
|
||||
|
||||
*value = _gtk_css_ident_value_try_parse (parser);
|
||||
g_assert (*value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_transition_time (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssValue **value = option_data;
|
||||
|
||||
*value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_TIME);
|
||||
|
||||
return *value != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_transition_timing_function (GtkCssParser *parser,
|
||||
gpointer option_data,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssValue **value = option_data;
|
||||
|
||||
*value = _gtk_css_ease_value_parse (parser);
|
||||
|
||||
return *value != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_one_transition (GtkCssShorthandProperty *shorthand,
|
||||
GtkCssValue **values,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* the image part */
|
||||
if (values[2] == NULL &&
|
||||
gtk_css_number_value_can_parse (parser) && !_gtk_css_parser_begins_with (parser, '-'))
|
||||
{
|
||||
GtkCssValue *number = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_TIME);
|
||||
const GtkCssParseOption options[] = {
|
||||
{ (void *) _gtk_css_ease_value_can_parse, parse_transition_timing_function, &values[3] },
|
||||
{ (void *) gtk_css_number_value_can_parse, parse_transition_time, &values[1] },
|
||||
{ (void *) gtk_css_number_value_can_parse, parse_transition_time, &values[2] },
|
||||
{ (void *) has_transition_property, parse_transition_property, &values[0] },
|
||||
};
|
||||
|
||||
if (number == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (values[1] == NULL)
|
||||
values[1] = number;
|
||||
else
|
||||
values[2] = number;
|
||||
}
|
||||
else if (values[3] == NULL &&
|
||||
_gtk_css_ease_value_can_parse (parser))
|
||||
{
|
||||
values[3] = _gtk_css_ease_value_parse (parser);
|
||||
|
||||
if (values[3] == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (values[0] == NULL)
|
||||
{
|
||||
values[0] = _gtk_css_ident_value_try_parse (parser);
|
||||
if (values[0] == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Unknown value for property");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We parsed everything and there's still stuff left?
|
||||
* Pretend we didn't notice and let the normal code produce
|
||||
* a 'junk at end of value' error
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!value_is_done_parsing (parser));
|
||||
|
||||
return TRUE;
|
||||
return gtk_css_parser_consume_any (parser, options, G_N_ELEMENTS (options), NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -699,7 +737,7 @@ parse_transition (GtkCssShorthandProperty *shorthand,
|
||||
g_ptr_array_add (arrays[i], step_values[i]);
|
||||
step_values[i] = NULL;
|
||||
}
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -717,7 +755,7 @@ parse_one_animation (GtkCssShorthandProperty *shorthand,
|
||||
{
|
||||
do
|
||||
{
|
||||
if (values[1] == NULL && _gtk_css_parser_try (parser, "infinite", TRUE))
|
||||
if (values[1] == NULL && gtk_css_parser_try_ident (parser, "infinite"))
|
||||
{
|
||||
values[1] = _gtk_css_number_value_new (HUGE_VAL, GTK_CSS_NUMBER);
|
||||
}
|
||||
@@ -816,7 +854,7 @@ parse_animation (GtkCssShorthandProperty *shorthand,
|
||||
g_ptr_array_add (arrays[i], step_values[i]);
|
||||
step_values[i] = NULL;
|
||||
}
|
||||
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
@@ -870,11 +908,11 @@ parse_font_variant (GtkCssShorthandProperty *shorthand,
|
||||
GtkCssValue **values,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "normal", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "normal"))
|
||||
{
|
||||
/* all initial values */
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "none", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "none"))
|
||||
{
|
||||
/* all initial values, except for font-variant-ligatures */
|
||||
values[0] = _gtk_css_font_variant_ligature_value_new (GTK_CSS_FONT_VARIANT_LIGATURE_NONE);
|
||||
@@ -896,13 +934,13 @@ parse_font_variant (GtkCssShorthandProperty *shorthand,
|
||||
parsed_ligature = _gtk_css_font_variant_ligature_try_parse_one (parser, ligatures);
|
||||
if (parsed_ligature == 0 && ligatures != 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid combination of ligature values");
|
||||
gtk_css_parser_error_value (parser, "Invalid combination of ligature values");
|
||||
return FALSE;
|
||||
}
|
||||
if (parsed_ligature == GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL ||
|
||||
parsed_ligature == GTK_CSS_FONT_VARIANT_LIGATURE_NONE)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Unexpected ligature value");
|
||||
gtk_css_parser_error_value (parser, "Unexpected ligature value");
|
||||
return FALSE;
|
||||
}
|
||||
if (parsed_ligature != ligatures)
|
||||
@@ -914,12 +952,12 @@ parse_font_variant (GtkCssShorthandProperty *shorthand,
|
||||
parsed_numeric = _gtk_css_font_variant_numeric_try_parse_one (parser, numeric);
|
||||
if (parsed_numeric == 0 && numeric != 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid combination of numeric values");
|
||||
gtk_css_parser_error_value (parser, "Invalid combination of numeric values");
|
||||
return FALSE;
|
||||
}
|
||||
if (parsed_numeric == GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Unexpected numeric value");
|
||||
gtk_css_parser_error_value (parser, "Unexpected numeric value");
|
||||
return FALSE;
|
||||
}
|
||||
if (parsed_numeric != numeric)
|
||||
@@ -931,12 +969,12 @@ parse_font_variant (GtkCssShorthandProperty *shorthand,
|
||||
parsed_east_asian = _gtk_css_font_variant_east_asian_try_parse_one (parser, east_asian);
|
||||
if (parsed_east_asian == 0 && east_asian != 0)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid combination of east asian values");
|
||||
gtk_css_parser_error_value (parser, "Invalid combination of east asian values");
|
||||
return FALSE;
|
||||
}
|
||||
if (parsed_east_asian == GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Unexpected east asian value");
|
||||
gtk_css_parser_error_value (parser, "Unexpected east asian value");
|
||||
return FALSE;
|
||||
}
|
||||
if (parsed_east_asian != east_asian)
|
||||
@@ -952,7 +990,7 @@ parse_font_variant (GtkCssShorthandProperty *shorthand,
|
||||
{
|
||||
if (_gtk_css_font_variant_position_value_get (values[1]) == GTK_CSS_FONT_VARIANT_POSITION_NORMAL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Unexpected position value");
|
||||
gtk_css_parser_error_value (parser, "Unexpected position value");
|
||||
return FALSE;
|
||||
}
|
||||
goto found;
|
||||
@@ -965,7 +1003,7 @@ parse_font_variant (GtkCssShorthandProperty *shorthand,
|
||||
{
|
||||
if (_gtk_css_font_variant_caps_value_get (values[2]) == GTK_CSS_FONT_VARIANT_CAPS_NORMAL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Unexpected caps value");
|
||||
gtk_css_parser_error_value (parser, "Unexpected caps value");
|
||||
return FALSE;
|
||||
}
|
||||
goto found;
|
||||
@@ -979,14 +1017,14 @@ parse_font_variant (GtkCssShorthandProperty *shorthand,
|
||||
{
|
||||
if (_gtk_css_font_variant_alternate_value_get (values[4]) == GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Unexpected alternate value");
|
||||
gtk_css_parser_error_value (parser, "Unexpected alternate value");
|
||||
return FALSE;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
_gtk_css_parser_error (parser, "Unknown value for property");
|
||||
gtk_css_parser_error_value (parser, "Unknown value for property");
|
||||
return FALSE;
|
||||
|
||||
found:
|
||||
@@ -1000,7 +1038,7 @@ found:
|
||||
values[0] = _gtk_css_font_variant_ligature_value_new (ligatures);
|
||||
if (values[0] == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid combination of ligature values");
|
||||
gtk_css_parser_error_value (parser, "Invalid combination of ligature values");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1010,7 +1048,7 @@ found:
|
||||
values[3] = _gtk_css_font_variant_numeric_value_new (numeric);
|
||||
if (values[3] == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid combination of numeric values");
|
||||
gtk_css_parser_error_value (parser, "Invalid combination of numeric values");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1020,7 +1058,7 @@ found:
|
||||
values[5] = _gtk_css_font_variant_east_asian_value_new (east_asian);
|
||||
if (values[5] == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid combination of east asian values");
|
||||
gtk_css_parser_error_value (parser, "Invalid combination of east asian values");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1034,7 +1072,7 @@ parse_all (GtkCssShorthandProperty *shorthand,
|
||||
GtkCssValue **values,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "The 'all' property can only be set to 'initial', 'inherit' or 'unset'");
|
||||
gtk_css_parser_error_syntax (parser, "The 'all' property can only be set to 'initial', 'inherit' or 'unset'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1119,7 +1157,7 @@ pack_font_description (GtkCssShorthandProperty *shorthand,
|
||||
|
||||
v = (* query_func) (GTK_CSS_PROPERTY_FONT_WEIGHT, query_data);
|
||||
if (v)
|
||||
pango_font_description_set_weight (description, _gtk_css_font_weight_value_get (v));
|
||||
pango_font_description_set_weight (description, _gtk_css_number_value_get (v, 100));
|
||||
|
||||
v = (* query_func) (GTK_CSS_PROPERTY_FONT_STRETCH, query_data);
|
||||
if (v)
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "gtkcssinheritvalueprivate.h"
|
||||
#include "gtkcssinitialvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcsssectionprivate.h"
|
||||
#include "gtkcssshorthandpropertyprivate.h"
|
||||
#include "gtkcssstringvalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
|
||||
@@ -160,7 +160,7 @@ _gtk_css_string_value_parse (GtkCssParser *parser)
|
||||
|
||||
g_return_val_if_fail (parser != NULL, NULL);
|
||||
|
||||
s = _gtk_css_parser_read_string (parser);
|
||||
s = gtk_css_parser_consume_string (parser);
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -200,9 +200,14 @@ _gtk_css_ident_value_try_parse (GtkCssParser *parser)
|
||||
|
||||
g_return_val_if_fail (parser != NULL, NULL);
|
||||
|
||||
ident = _gtk_css_parser_try_ident (parser, TRUE);
|
||||
if (ident == NULL)
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||
return NULL;
|
||||
|
||||
ident = gtk_css_parser_consume_ident (parser);
|
||||
if (ident == NULL)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return _gtk_css_ident_value_new_take (ident);
|
||||
}
|
||||
|
||||
+1
-2
@@ -29,7 +29,6 @@
|
||||
#include "gtkcssinitialvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcsssectionprivate.h"
|
||||
#include "gtkcssshorthandpropertyprivate.h"
|
||||
#include "gtkcssstringvalueprivate.h"
|
||||
#include "gtkcssfontfeaturesvalueprivate.h"
|
||||
@@ -162,7 +161,7 @@ gtk_css_style_print (GtkCssStyle *style,
|
||||
if (section)
|
||||
{
|
||||
g_string_append (string, " /* ");
|
||||
_gtk_css_section_print (section, string);
|
||||
gtk_css_section_print (section, string);
|
||||
g_string_append (string, " */");
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
#define __GTK_CSS_STYLE_PRIVATE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtk/css/gtkcss.h>
|
||||
|
||||
#include "gtk/gtkbitmaskprivate.h"
|
||||
#include "gtk/gtkcsssection.h"
|
||||
#include "gtk/gtkcssvalueprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -142,14 +142,14 @@ gtk_css_style_property_parse_value (GtkStyleProperty *property,
|
||||
{
|
||||
GtkCssStyleProperty *style_property = GTK_CSS_STYLE_PROPERTY (property);
|
||||
|
||||
if (_gtk_css_parser_try (parser, "initial", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "initial"))
|
||||
{
|
||||
/* the initial value can be explicitly specified with the
|
||||
* ‘initial’ keyword which all properties accept.
|
||||
*/
|
||||
return _gtk_css_initial_value_new ();
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "inherit", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "inherit"))
|
||||
{
|
||||
/* All properties accept the ‘inherit’ value which
|
||||
* explicitly specifies that the value will be determined
|
||||
@@ -159,7 +159,7 @@ gtk_css_style_property_parse_value (GtkStyleProperty *property,
|
||||
*/
|
||||
return _gtk_css_inherit_value_new ();
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "unset", TRUE))
|
||||
else if (gtk_css_parser_try_ident (parser, "unset"))
|
||||
{
|
||||
/* If the cascaded value of a property is the unset keyword,
|
||||
* then if it is an inherited property, this is treated as
|
||||
|
||||
@@ -159,13 +159,16 @@ font_family_parse_one (GtkCssParser *parser)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = _gtk_css_parser_try_ident (parser, TRUE);
|
||||
if (name)
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
GString *string = g_string_new (name);
|
||||
GString *string = g_string_new (NULL);
|
||||
|
||||
name = gtk_css_parser_consume_ident (parser);
|
||||
g_string_append (string, name);
|
||||
g_free (name);
|
||||
while ((name = _gtk_css_parser_try_ident (parser, TRUE)))
|
||||
while (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
name = gtk_css_parser_consume_ident (parser);
|
||||
g_string_append_c (string, ' ');
|
||||
g_string_append (string, name);
|
||||
g_free (name);
|
||||
@@ -174,7 +177,7 @@ font_family_parse_one (GtkCssParser *parser)
|
||||
}
|
||||
else
|
||||
{
|
||||
name = _gtk_css_parser_read_string (parser);
|
||||
name = gtk_css_parser_consume_string (parser);
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
}
|
||||
@@ -224,7 +227,7 @@ font_style_parse (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_font_style_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown font style value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -242,10 +245,22 @@ static GtkCssValue *
|
||||
font_weight_parse (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssValue *value = _gtk_css_font_weight_value_try_parse (parser);
|
||||
GtkCssValue *value;
|
||||
|
||||
value = gtk_css_font_weight_value_try_parse (parser);
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
{
|
||||
value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_POSITIVE_ONLY);
|
||||
if (value == NULL)
|
||||
return NULL;
|
||||
|
||||
if (_gtk_css_number_value_get (value, 100) < 1 ||
|
||||
_gtk_css_number_value_get (value, 100) > 1000)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Font weight values must be between 1 and 1000");
|
||||
g_clear_pointer (&value, gtk_css_value_unref);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -256,7 +271,7 @@ font_weight_query (GtkCssStyleProperty *property,
|
||||
GValue *value)
|
||||
{
|
||||
g_value_init (value, PANGO_TYPE_WEIGHT);
|
||||
g_value_set_enum (value, _gtk_css_font_weight_value_get (css_value));
|
||||
g_value_set_enum (value, _gtk_css_number_value_get (css_value, 100));
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
@@ -266,7 +281,7 @@ font_stretch_parse (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_font_stretch_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown font stretch value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -287,7 +302,7 @@ parse_border_style (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_border_style_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown border style value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -307,7 +322,7 @@ parse_css_area_one (GtkCssParser *parser)
|
||||
GtkCssValue *value = _gtk_css_area_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown box value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -325,7 +340,7 @@ parse_one_css_direction (GtkCssParser *parser)
|
||||
GtkCssValue *value = _gtk_css_direction_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown direction value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -360,7 +375,7 @@ parse_one_css_play_state (GtkCssParser *parser)
|
||||
GtkCssValue *value = _gtk_css_play_state_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown play state value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -378,7 +393,7 @@ parse_one_css_fill_mode (GtkCssParser *parser)
|
||||
GtkCssValue *value = _gtk_css_fill_mode_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown fill mode value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -414,7 +429,7 @@ icon_style_parse (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_icon_style_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown icon style value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -433,7 +448,7 @@ parse_text_decoration_line (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_text_decoration_line_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown text decoration line value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -445,7 +460,7 @@ parse_text_decoration_style (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_text_decoration_style_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown text decoration style value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -457,7 +472,7 @@ parse_font_kerning (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_font_kerning_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown font kerning value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -465,10 +480,10 @@ parse_font_kerning (GtkCssStyleProperty *property,
|
||||
static gboolean
|
||||
value_is_done_parsing (GtkCssParser *parser)
|
||||
{
|
||||
return _gtk_css_parser_is_eof (parser) ||
|
||||
_gtk_css_parser_begins_with (parser, ',') ||
|
||||
_gtk_css_parser_begins_with (parser, ';') ||
|
||||
_gtk_css_parser_begins_with (parser, '}');
|
||||
return gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF) ||
|
||||
gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_COMMA) ||
|
||||
gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SEMICOLON) ||
|
||||
gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_CLOSE_CURLY);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
@@ -485,7 +500,7 @@ parse_font_variant_ligatures (GtkCssStyleProperty *property,
|
||||
parsed = _gtk_css_font_variant_ligature_try_parse_one (parser, ligatures);
|
||||
if (parsed == 0 || parsed == ligatures)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid value");
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid value");
|
||||
return NULL;
|
||||
}
|
||||
ligatures = parsed;
|
||||
@@ -493,7 +508,7 @@ parse_font_variant_ligatures (GtkCssStyleProperty *property,
|
||||
|
||||
value = _gtk_css_font_variant_ligature_value_new (ligatures);
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "Invalid combination of values");
|
||||
gtk_css_parser_error_syntax (parser, "Invalid combination of values");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -505,7 +520,7 @@ parse_font_variant_position (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_font_variant_position_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown font variant position value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -517,7 +532,7 @@ parse_font_variant_caps (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_font_variant_caps_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown font variant caps value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -536,7 +551,7 @@ parse_font_variant_numeric (GtkCssStyleProperty *property,
|
||||
parsed = _gtk_css_font_variant_numeric_try_parse_one (parser, numeric);
|
||||
if (parsed == 0 || parsed == numeric)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid value");
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid value");
|
||||
return NULL;
|
||||
}
|
||||
numeric = parsed;
|
||||
@@ -544,7 +559,7 @@ parse_font_variant_numeric (GtkCssStyleProperty *property,
|
||||
|
||||
value = _gtk_css_font_variant_numeric_value_new (numeric);
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "Invalid combination of values");
|
||||
gtk_css_parser_error_syntax (parser, "Invalid combination of values");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -556,7 +571,7 @@ parse_font_variant_alternates (GtkCssStyleProperty *property,
|
||||
GtkCssValue *value = _gtk_css_font_variant_alternate_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "unknown font variant alternate value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -575,7 +590,7 @@ parse_font_variant_east_asian (GtkCssStyleProperty *property,
|
||||
parsed = _gtk_css_font_variant_east_asian_try_parse_one (parser, east_asian);
|
||||
if (parsed == 0 || parsed == east_asian)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid value");
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid value");
|
||||
return NULL;
|
||||
}
|
||||
east_asian = parsed;
|
||||
@@ -583,7 +598,7 @@ parse_font_variant_east_asian (GtkCssStyleProperty *property,
|
||||
|
||||
value = _gtk_css_font_variant_east_asian_value_new (east_asian);
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "Invalid combination of values");
|
||||
gtk_css_parser_error_syntax (parser, "Invalid combination of values");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -650,7 +665,7 @@ css_image_value_parse (GtkCssStyleProperty *property,
|
||||
{
|
||||
GtkCssImage *image;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "none", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
image = NULL;
|
||||
else
|
||||
{
|
||||
@@ -666,7 +681,7 @@ static GtkCssValue *
|
||||
css_image_value_parse_with_builtin (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "builtin", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "builtin"))
|
||||
return _gtk_css_image_value_new (gtk_css_image_builtin_new ());
|
||||
|
||||
return css_image_value_parse (property, parser);
|
||||
@@ -730,7 +745,7 @@ border_image_repeat_parse (GtkCssStyleProperty *property,
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid value");
|
||||
gtk_css_parser_error_syntax (parser, "Not a valid border repeat value");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -780,7 +795,7 @@ transition_property_parse_one (GtkCssParser *parser)
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected an identifier");
|
||||
gtk_css_parser_error_syntax (parser, "Expected an identifier");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -817,7 +832,7 @@ transition_timing_function_parse (GtkCssStyleProperty *property,
|
||||
static GtkCssValue *
|
||||
iteration_count_parse_one (GtkCssParser *parser)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "infinite", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "infinite"))
|
||||
return _gtk_css_number_value_new (HUGE_VAL, GTK_CSS_NUMBER);
|
||||
|
||||
return _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_POSITIVE_ONLY);
|
||||
@@ -862,7 +877,7 @@ blend_mode_value_parse_one (GtkCssParser *parser)
|
||||
GtkCssValue *value = _gtk_css_blend_mode_value_try_parse (parser);
|
||||
|
||||
if (value == NULL)
|
||||
_gtk_css_parser_error (parser, "unknown value for property");
|
||||
gtk_css_parser_error_syntax (parser, "Unknown blend mode value");
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -881,7 +896,7 @@ background_repeat_value_parse_one (GtkCssParser *parser)
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Not a valid value");
|
||||
gtk_css_parser_error_syntax (parser, "Unknown repeat value");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1001,7 +1016,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_AFFECTS_TEXT_SIZE,
|
||||
font_weight_parse,
|
||||
font_weight_query,
|
||||
_gtk_css_font_weight_value_new (PANGO_WEIGHT_NORMAL));
|
||||
_gtk_css_number_value_new (PANGO_WEIGHT_NORMAL, GTK_CSS_NUMBER));
|
||||
gtk_css_style_property_register ("font-stretch",
|
||||
GTK_CSS_PROPERTY_FONT_STRETCH,
|
||||
PANGO_TYPE_STRETCH,
|
||||
|
||||
+327
-320
@@ -826,332 +826,102 @@ gtk_css_transform_value_is_none (const GtkCssValue *value)
|
||||
return value->n_transforms == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_transform_parse (GtkCssTransform *transform,
|
||||
GtkCssParser *parser)
|
||||
static guint
|
||||
gtk_css_transform_parse_float (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, "matrix(", TRUE))
|
||||
{
|
||||
double xx, xy, x0, yx, yy, y0;
|
||||
transform->type = GTK_CSS_TRANSFORM_MATRIX;
|
||||
float *f = data;
|
||||
double d;
|
||||
|
||||
/* FIXME: Improve error handling here */
|
||||
if (!_gtk_css_parser_try_double (parser, &xx)
|
||||
|| !_gtk_css_parser_try (parser, ",", TRUE)
|
||||
|| !_gtk_css_parser_try_double (parser, &xy)
|
||||
|| !_gtk_css_parser_try (parser, ",", TRUE)
|
||||
|| !_gtk_css_parser_try_double (parser, &x0)
|
||||
|| !_gtk_css_parser_try (parser, ",", TRUE)
|
||||
|| !_gtk_css_parser_try_double (parser, &yx)
|
||||
|| !_gtk_css_parser_try (parser, ",", TRUE)
|
||||
|| !_gtk_css_parser_try_double (parser, &yy)
|
||||
|| !_gtk_css_parser_try (parser, ",", TRUE)
|
||||
|| !_gtk_css_parser_try_double (parser, &y0))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "invalid syntax for matrix()");
|
||||
return FALSE;
|
||||
}
|
||||
graphene_matrix_init_from_2d (&transform->matrix.matrix,
|
||||
xx, yx, xy, yy, x0, y0);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "matrix3d(", TRUE))
|
||||
{
|
||||
float f[16];
|
||||
double d;
|
||||
guint i;
|
||||
if (!gtk_css_parser_consume_number (parser, &d))
|
||||
return 0;
|
||||
|
||||
transform->type = GTK_CSS_TRANSFORM_MATRIX;
|
||||
f[n] = d;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (!_gtk_css_parser_try_double (parser, &d))
|
||||
break;
|
||||
f[i] = d;
|
||||
static guint
|
||||
gtk_css_transform_parse_length (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssValue **values = data;
|
||||
|
||||
if (i < 15 && !_gtk_css_parser_try (parser, ",", TRUE))
|
||||
break;
|
||||
}
|
||||
values[n] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (values[n] == NULL)
|
||||
return 0;
|
||||
|
||||
if (i < 16)
|
||||
{
|
||||
/* FIXME: Improve error handling here */
|
||||
_gtk_css_parser_error (parser, "invalid syntax for matrix3d()");
|
||||
return FALSE;
|
||||
}
|
||||
graphene_matrix_init_from_float (&transform->matrix.matrix, f);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "translate(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
transform->translate.x = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->translate.x == NULL)
|
||||
return FALSE;
|
||||
static guint
|
||||
gtk_css_transform_parse_angle (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssValue **values = data;
|
||||
|
||||
if (_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
transform->translate.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->translate.y == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (transform->translate.x);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transform->translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
transform->translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "translateX(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
values[n] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (values[n] == NULL)
|
||||
return 0;
|
||||
|
||||
transform->translate.x = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->translate.x == NULL)
|
||||
return FALSE;
|
||||
|
||||
transform->translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
transform->translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "translateY(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
transform->translate.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->translate.y == NULL)
|
||||
return FALSE;
|
||||
|
||||
transform->translate.x = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
transform->translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "translateZ(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
static guint
|
||||
gtk_css_transform_parse_number (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssValue **values = data;
|
||||
|
||||
transform->translate.z = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->translate.z == NULL)
|
||||
return FALSE;
|
||||
|
||||
transform->translate.x = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
transform->translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "translate3d(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
values[n] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (values[n] == NULL)
|
||||
return 0;
|
||||
|
||||
transform->translate.x = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->translate.x != NULL)
|
||||
{
|
||||
transform->translate.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->translate.y != NULL)
|
||||
{
|
||||
transform->translate.z = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->translate.z != NULL)
|
||||
goto out;
|
||||
}
|
||||
_gtk_css_value_unref (transform->translate.y);
|
||||
}
|
||||
|
||||
_gtk_css_value_unref (transform->translate.x);
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "scale(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_SCALE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
transform->scale.x = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->scale.x == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
transform->scale.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->scale.y == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (transform->scale.x);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transform->scale.y = _gtk_css_value_ref (transform->scale.x);
|
||||
}
|
||||
transform->scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "scaleX(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_SCALE;
|
||||
|
||||
transform->scale.x = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->scale.x == NULL)
|
||||
return FALSE;
|
||||
|
||||
transform->scale.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform->scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "scaleY(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_SCALE;
|
||||
|
||||
transform->scale.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->scale.y == NULL)
|
||||
return FALSE;
|
||||
|
||||
transform->scale.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform->scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "scaleZ(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_SCALE;
|
||||
|
||||
transform->scale.z = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->scale.z == NULL)
|
||||
return FALSE;
|
||||
|
||||
transform->scale.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform->scale.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "scale3d(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_SCALE;
|
||||
|
||||
transform->scale.x = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->scale.x != NULL)
|
||||
{
|
||||
transform->scale.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->scale.y != NULL)
|
||||
{
|
||||
transform->scale.z = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->scale.z != NULL)
|
||||
goto out;
|
||||
}
|
||||
_gtk_css_value_unref (transform->scale.y);
|
||||
}
|
||||
|
||||
_gtk_css_value_unref (transform->scale.x);
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "rotate(", TRUE) ||
|
||||
_gtk_css_parser_try (parser, "rotateZ(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_ROTATE;
|
||||
|
||||
transform->rotate.angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->rotate.angle == NULL)
|
||||
return FALSE;
|
||||
transform->rotate.x = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
transform->rotate.y = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
transform->rotate.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "rotateX(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_ROTATE;
|
||||
|
||||
transform->rotate.angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->rotate.angle == NULL)
|
||||
return FALSE;
|
||||
transform->rotate.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform->rotate.y = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
transform->rotate.z = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "rotateY(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_ROTATE;
|
||||
|
||||
transform->rotate.angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->rotate.angle == NULL)
|
||||
return FALSE;
|
||||
transform->rotate.x = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
transform->rotate.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform->rotate.z = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "rotate3d(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_ROTATE;
|
||||
static guint
|
||||
gtk_css_transform_parse_rotate3d (GtkCssParser *parser,
|
||||
guint n,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssTransform *transform = data;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 0:
|
||||
transform->rotate.x = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->rotate.x != NULL)
|
||||
{
|
||||
transform->rotate.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->rotate.y != NULL)
|
||||
{
|
||||
transform->rotate.z = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->rotate.z != NULL)
|
||||
{
|
||||
transform->rotate.angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->rotate.angle != NULL)
|
||||
goto out;
|
||||
}
|
||||
_gtk_css_value_unref (transform->rotate.z);
|
||||
}
|
||||
_gtk_css_value_unref (transform->rotate.y);
|
||||
}
|
||||
_gtk_css_value_unref (transform->rotate.x);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "skew(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_SKEW;
|
||||
if (transform->rotate.x == NULL)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
transform->skew.x = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->skew.x == NULL)
|
||||
return FALSE;
|
||||
case 1:
|
||||
transform->rotate.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->rotate.y == NULL)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
if (_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
transform->skew.y = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->skew.y == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (transform->skew.x);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transform->skew.y = _gtk_css_number_value_new (0, GTK_CSS_DEG);
|
||||
}
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "skewX(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_SKEW_X;
|
||||
case 2:
|
||||
transform->rotate.z = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
|
||||
if (transform->rotate.z == NULL)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
transform->skew_x.skew = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->skew_x.skew == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "skewY(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_SKEW_Y;
|
||||
case 3:
|
||||
transform->rotate.angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->rotate.angle == NULL)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
transform->skew_y.skew = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
|
||||
if (transform->skew_y.skew == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "perspective(", TRUE))
|
||||
{
|
||||
transform->type = GTK_CSS_TRANSFORM_PERSPECTIVE;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
return 0;
|
||||
}
|
||||
|
||||
transform->perspective.depth = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH);
|
||||
if (transform->perspective.depth == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "unknown syntax for transform");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
out:
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
gtk_css_transform_clear (transform);
|
||||
_gtk_css_parser_error (parser, "Expected closing ')'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
@@ -1161,25 +931,254 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
|
||||
GArray *array;
|
||||
guint i;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "none", TRUE))
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
return _gtk_css_transform_value_new_none ();
|
||||
|
||||
array = g_array_new (FALSE, FALSE, sizeof (GtkCssTransform));
|
||||
|
||||
do {
|
||||
GtkCssTransform transform;
|
||||
while (TRUE)
|
||||
{
|
||||
GtkCssTransform transform;
|
||||
|
||||
if (!gtk_css_transform_parse (&transform, parser))
|
||||
{
|
||||
for (i = 0; i < array->len; i++)
|
||||
{
|
||||
gtk_css_transform_clear (&g_array_index (array, GtkCssTransform, i));
|
||||
}
|
||||
g_array_free (array, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
g_array_append_val (array, transform);
|
||||
} while (!_gtk_css_parser_begins_with (parser, ';'));
|
||||
if (gtk_css_parser_has_function (parser, "matrix"))
|
||||
{
|
||||
float f[6];
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 6, 6, gtk_css_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_MATRIX;
|
||||
graphene_matrix_init_from_2d (&transform.matrix.matrix, f[0], f[1], f[2], f[3], f[4], f[5]);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "matrix3d"))
|
||||
{
|
||||
float f[16];
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 16, 16, gtk_css_transform_parse_float, f))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_MATRIX;
|
||||
graphene_matrix_init_from_float (&transform.matrix.matrix, f);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "perspective"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_length, &transform.perspective.depth))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_PERSPECTIVE;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "rotate") ||
|
||||
gtk_css_parser_has_function (parser, "rotateZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_angle, &transform.rotate.angle))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_ROTATE;
|
||||
transform.rotate.x = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
transform.rotate.y = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
transform.rotate.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "rotate3d"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 4, 4, gtk_css_transform_parse_rotate3d, &transform))
|
||||
{
|
||||
g_clear_pointer (&transform.rotate.x, gtk_css_value_unref);
|
||||
g_clear_pointer (&transform.rotate.y, gtk_css_value_unref);
|
||||
g_clear_pointer (&transform.rotate.z, gtk_css_value_unref);
|
||||
g_clear_pointer (&transform.rotate.angle, gtk_css_value_unref);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_ROTATE;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "rotateX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_angle, &transform.rotate.angle))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_ROTATE;
|
||||
transform.rotate.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform.rotate.y = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
transform.rotate.z = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "rotateY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_angle, &transform.rotate.angle))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_ROTATE;
|
||||
transform.rotate.x = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
transform.rotate.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform.rotate.z = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "scale"))
|
||||
{
|
||||
GtkCssValue *values[2] = { NULL, NULL };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 2, gtk_css_transform_parse_number, values))
|
||||
{
|
||||
g_clear_pointer (&values[0], gtk_css_value_unref);
|
||||
g_clear_pointer (&values[1], gtk_css_value_unref);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_SCALE;
|
||||
transform.scale.x = values[0];
|
||||
if (values[1])
|
||||
transform.scale.y = values[1];
|
||||
else
|
||||
transform.scale.y = gtk_css_value_ref (values[0]);
|
||||
transform.scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "scale3d"))
|
||||
{
|
||||
GtkCssValue *values[3] = { NULL, NULL };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 3, gtk_css_transform_parse_number, values))
|
||||
{
|
||||
g_clear_pointer (&values[0], gtk_css_value_unref);
|
||||
g_clear_pointer (&values[1], gtk_css_value_unref);
|
||||
g_clear_pointer (&values[2], gtk_css_value_unref);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_SCALE;
|
||||
transform.scale.x = values[0];
|
||||
transform.scale.y = values[1];
|
||||
transform.scale.z = values[2];
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "scaleX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_number, &transform.scale.x))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_SCALE;
|
||||
transform.scale.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform.scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "scaleY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_number, &transform.scale.y))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_SCALE;
|
||||
transform.scale.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform.scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "scaleZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_number, &transform.scale.z))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_SCALE;
|
||||
transform.scale.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
transform.scale.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "skew"))
|
||||
{
|
||||
GtkCssValue *values[2] = { NULL, NULL };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 2, 2, gtk_css_transform_parse_angle, values))
|
||||
{
|
||||
g_clear_pointer (&values[0], gtk_css_value_unref);
|
||||
g_clear_pointer (&values[1], gtk_css_value_unref);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_SKEW;
|
||||
transform.skew.x = values[0];
|
||||
transform.skew.y = values[1];
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "skewX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_angle, &transform.skew_x.skew))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_SKEW_X;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "skewY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_angle, &transform.skew_y.skew))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_SKEW_Y;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "translate"))
|
||||
{
|
||||
GtkCssValue *values[2] = { NULL, NULL };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 2, gtk_css_transform_parse_length, values))
|
||||
{
|
||||
g_clear_pointer (&values[0], gtk_css_value_unref);
|
||||
g_clear_pointer (&values[1], gtk_css_value_unref);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
transform.translate.x = values[0];
|
||||
if (values[1])
|
||||
transform.translate.y = values[1];
|
||||
else
|
||||
transform.translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
transform.translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "translate3d"))
|
||||
{
|
||||
GtkCssValue *values[3] = { NULL, NULL };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 3, gtk_css_transform_parse_length, values))
|
||||
{
|
||||
g_clear_pointer (&values[0], gtk_css_value_unref);
|
||||
g_clear_pointer (&values[1], gtk_css_value_unref);
|
||||
g_clear_pointer (&values[2], gtk_css_value_unref);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
transform.translate.x = values[0];
|
||||
transform.translate.y = values[1];
|
||||
transform.translate.z = values[2];
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "translateX"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_length, &transform.translate.x))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
transform.translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
transform.translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "translateY"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_length, &transform.translate.y))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
transform.translate.x = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
transform.translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "translateZ"))
|
||||
{
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_transform_parse_length, &transform.translate.z))
|
||||
goto fail;
|
||||
|
||||
transform.type = GTK_CSS_TRANSFORM_TRANSLATE;
|
||||
transform.translate.x = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
transform.translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
g_array_append_val (array, transform);
|
||||
}
|
||||
|
||||
if (array->len == 0)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a transform");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
value = gtk_css_transform_value_alloc (array->len);
|
||||
memcpy (value->transforms, array->data, sizeof (GtkCssTransform) * array->len);
|
||||
@@ -1187,6 +1186,14 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
|
||||
g_array_free (array, TRUE);
|
||||
|
||||
return value;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < array->len; i++)
|
||||
{
|
||||
gtk_css_transform_clear (&g_array_index (array, GtkCssTransform, i));
|
||||
}
|
||||
g_array_free (array, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GskTransform *
|
||||
|
||||
@@ -36,7 +36,7 @@ gtk_custom_layout_get_request_mode (GtkLayoutManager *manager,
|
||||
if (self->request_mode_func != NULL)
|
||||
return self->request_mode_func (widget);
|
||||
|
||||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
return GTK_LAYOUT_MANAGER_CLASS (gtk_custom_layout_parent_class)->get_request_mode (manager, widget);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+1
-1
@@ -3117,7 +3117,7 @@ gtk_entry_ensure_progress_widget (GtkEntry *entry)
|
||||
priv->progress_widget = g_object_new (GTK_TYPE_PROGRESS_BAR,
|
||||
"css-name", "progress",
|
||||
NULL);
|
||||
gtk_widget_set_can_pick (priv->progress_widget, FALSE);
|
||||
gtk_widget_set_can_target (priv->progress_widget, FALSE);
|
||||
|
||||
gtk_widget_set_parent (priv->progress_widget, GTK_WIDGET (entry));
|
||||
|
||||
|
||||
@@ -1040,4 +1040,18 @@ typedef enum {
|
||||
GTK_PLACES_OPEN_NEW_WINDOW = 1 << 2
|
||||
} GtkPlacesOpenFlags;
|
||||
|
||||
/**
|
||||
* GtkPickFlags:
|
||||
* @GTK_PICK_DEFAULT: The default behavior, include widgets that are receiving events
|
||||
* @GTK_PICK_INSENSITIVE: Include widgets that are insensitive
|
||||
* @GTK_PICK_NON_TARGETABLE: Include widgets that are marked as non-targetable. See #GtkWidget::can-target
|
||||
*
|
||||
* Flags that influence the behavior of gtk_widget_pick()
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_PICK_DEFAULT = 0,
|
||||
GTK_PICK_INSENSITIVE = 1 << 0,
|
||||
GTK_PICK_NON_TARGETABLE = 1 << 1
|
||||
} GtkPickFlags;
|
||||
|
||||
#endif /* __GTK_ENUMS_H__ */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user