aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Arias Mallo <rodarima@gmail.com>2024-07-27 12:52:51 +0200
committerRodrigo Arias Mallo <rodarima@gmail.com>2024-07-27 12:54:47 +0200
commitc2081d28740e03d43b9dbbe9dbd5ac6484e8953a (patch)
treeeb1c8ac0965fee0139ee58db131a142b2150b4c8
parent59b746f013f60050b91cb5f6f8dd4a96c47f380e (diff)
Add SVG support for currentColor
The currentColor special value for the fill and stroke attributes allows an image to follow the same foreground color of the surounding text.
-rw-r--r--dw/widget.cc17
-rw-r--r--dw/widget.hh21
-rw-r--r--src/dicache.c5
-rw-r--r--src/html.cc5
-rw-r--r--src/image.cc8
-rw-r--r--src/image.hh6
-rw-r--r--src/nanosvg.h21
-rw-r--r--src/styleengine.cc2
-rw-r--r--src/svg.c11
9 files changed, 77 insertions, 19 deletions
diff --git a/dw/widget.cc b/dw/widget.cc
index edabce51..865023a1 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -1361,6 +1361,23 @@ style::Color *Widget::getBgColor ()
return layout->getBgColor ();
}
+/**
+ * \brief Get the actual foreground color of a widget.
+ */
+style::Color *Widget::getFgColor ()
+{
+ Widget *widget = this;
+
+ while (widget != NULL) {
+ if (widget->style->color)
+ return widget->style->color;
+
+ widget = widget->parent;
+ }
+
+ return NULL;
+}
+
/**
* \brief Draw borders and background of a widget part, which allocation is
diff --git a/dw/widget.hh b/dw/widget.hh
index cf0ffe46..d1957d4f 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -1,3 +1,23 @@
+/*
+ * Dillo Widget
+ *
+ * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org>
+ * Copyright 2023-2024 Rodrigo Arias Mallo <rodarima@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
#ifndef __DW_WIDGET_HH__
#define __DW_WIDGET_HH__
@@ -540,6 +560,7 @@ public:
virtual void setStyle (style::Style *style);
void setBgColor (style::Color *bgColor);
style::Color *getBgColor ();
+ style::Color *getFgColor ();
void drawBox (View *view, style::Style *style, Rectangle *area,
int x, int y, int width, int height, bool inverse);
diff --git a/src/dicache.c b/src/dicache.c
index 1419ff7a..c9f4067b 100644
--- a/src/dicache.c
+++ b/src/dicache.c
@@ -2,6 +2,7 @@
* File: dicache.c
*
* Copyright 2000-2007 Jorge Arellano Cid <jcid@dillo.org>
+ * Copyright 2024 Rodrigo Arias Mallo <rodarima@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -353,7 +354,7 @@ void a_Dicache_close(DilloUrl *url, int version, CacheClient_t *Client)
/* ------------------------------------------------------------------------- */
/**
- * Generic MIME handler for GIF, JPEG and PNG.
+ * Generic MIME handler for GIF, JPEG, PNG and SVG.
* Sets a_Dicache_callback as the cache-client,
* and also sets the image decoder.
*
@@ -372,7 +373,7 @@ static void *Dicache_image(int ImgType, const char *MimeType, void *Ptr,
if (!web->Image) {
web->Image =
- a_Image_new_with_dw(web->bw->render_layout, NULL, web->bgColor);
+ a_Image_new_with_dw(web->bw->render_layout, NULL, web->bgColor, 0);
a_Image_ref(web->Image);
}
diff --git a/src/html.cc b/src/html.cc
index a55fd2a8..4e2b73d1 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -2149,13 +2149,16 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize)
dw::Image *dw = new dw::Image(alt_ptr);
image =
- a_Image_new(html->dw->getLayout(), (void*)(dw::core::ImgRenderer*)dw, 0);
+ a_Image_new(html->dw->getLayout(), (void*)(dw::core::ImgRenderer*)dw, 0, 0);
a_Image_ref(image);
if (HT2TB(html)->getBgColor())
image->bg_color = HT2TB(html)->getBgColor()->getColor();
+ if (HT2TB(html)->getFgColor())
+ image->fg_color = HT2TB(html)->getFgColor()->getColor();
+
DilloHtmlImage *hi = dNew(DilloHtmlImage, 1);
hi->url = url;
html->images->increase();
diff --git a/src/image.cc b/src/image.cc
index c9862661..ae85569c 100644
--- a/src/image.cc
+++ b/src/image.cc
@@ -31,7 +31,8 @@ using namespace dw::core;
/**
* Create and initialize a new image structure.
*/
-DilloImage *a_Image_new(void *layout, void *img_rndr, int32_t bg_color)
+DilloImage *a_Image_new(void *layout, void *img_rndr,
+ int32_t bg_color, int32_t fg_color)
{
DilloImage *Image;
@@ -42,6 +43,7 @@ DilloImage *a_Image_new(void *layout, void *img_rndr, int32_t bg_color)
Image->height = 0;
Image->dpi = ((Layout *) layout)->dpiX();
Image->bg_color = bg_color;
+ Image->fg_color = fg_color;
Image->ScanNumber = 0;
Image->BitVec = NULL;
Image->State = IMG_Empty;
@@ -55,10 +57,10 @@ DilloImage *a_Image_new(void *layout, void *img_rndr, int32_t bg_color)
* Create and initialize a new image structure with an image widget.
*/
DilloImage *a_Image_new_with_dw(void *layout, const char *alt_text,
- int32_t bg_color)
+ int32_t bg_color, int32_t fg_color)
{
dw::Image *dw = new dw::Image(alt_text);
- return a_Image_new(layout, (void*)(dw::core::ImgRenderer*)dw, bg_color);
+ return a_Image_new(layout, (void*)(dw::core::ImgRenderer*)dw, bg_color, fg_color);
}
/**
diff --git a/src/image.hh b/src/image.hh
index a5057227..2dc87ecc 100644
--- a/src/image.hh
+++ b/src/image.hh
@@ -66,6 +66,7 @@ struct _DilloImage {
float dpi; /**< Dots per inch */
int32_t bg_color; /**< Background color */
+ int32_t fg_color; /**< Foreground color */
bitvec_t *BitVec; /**< Bit vector for decoded rows */
uint_t ScanNumber; /**< Current decoding scan */
ImageState State; /**< Processing status */
@@ -77,9 +78,10 @@ struct _DilloImage {
/*
* Function prototypes
*/
-DilloImage *a_Image_new(void *layout, void *img_rndr, int32_t bg_color);
+DilloImage *a_Image_new(void *layout, void *img_rndr,
+ int32_t bg_color, int32_t fg_color);
DilloImage *a_Image_new_with_dw(void *layout, const char *alt_text,
- int32_t bg_color);
+ int32_t bg_color, int32_t fg_color);
void *a_Image_get_dw(DilloImage *Image);
void a_Image_ref(DilloImage *Image);
void a_Image_unref(DilloImage *Image);
diff --git a/src/nanosvg.h b/src/nanosvg.h
index e4bfa760..98b06bea 100644
--- a/src/nanosvg.h
+++ b/src/nanosvg.h
@@ -165,15 +165,16 @@ typedef struct NSVGimage
{
float width; // Width of the image.
float height; // Height of the image.
+ unsigned current_color; // For "currentColor"
NSVGshape* shapes; // Linked list of shapes in the image.
} NSVGimage;
// Parses SVG file from a file, returns SVG image as paths.
-NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi);
+NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi, unsigned current_color);
// Parses SVG file from a null terminated string, returns SVG image as paths.
// Important note: changes the string.
-NSVGimage* nsvgParse(char* input, const char* units, float dpi);
+NSVGimage* nsvgParse(char* input, const char* units, float dpi, unsigned current_color);
// Duplicates a path.
NSVGpath* nsvgDuplicatePath(NSVGpath* p);
@@ -616,7 +617,7 @@ static void nsvg__curveBounds(float* bounds, float* curve)
}
}
-static NSVGparser* nsvg__createParser(void)
+static NSVGparser* nsvg__createParser(unsigned current_color)
{
NSVGparser* p;
p = (NSVGparser*)malloc(sizeof(NSVGparser));
@@ -646,6 +647,8 @@ static NSVGparser* nsvg__createParser(void)
/* TODO: Let the user change the initial value */
p->attr[0].fontSize = 40.0f;
+ p->image->current_color = current_color;
+
return p;
error:
@@ -1810,7 +1813,7 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
nsvg__parseUrl(attr->fillGradient, value);
} else if (strncmp(value, "currentColor", 12) == 0) {
attr->hasFill = 1;
- attr->fillColor = 0; /* TODO: Black by default */
+ attr->fillColor = p->image->current_color;
} else {
attr->hasFill = 1;
attr->fillColor = nsvg__parseColor(value);
@@ -1827,7 +1830,7 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
nsvg__parseUrl(attr->strokeGradient, value);
} else if (strncmp(value, "currentColor", 12) == 0) {
attr->hasStroke = 1;
- attr->strokeColor = 0; /* TODO: Black by default */
+ attr->strokeColor = p->image->current_color;
} else {
attr->hasStroke = 1;
attr->strokeColor = nsvg__parseColor(value);
@@ -3097,12 +3100,12 @@ static void nsvg__createGradients(NSVGparser* p)
}
}
-NSVGimage* nsvgParse(char* input, const char* units, float dpi)
+NSVGimage* nsvgParse(char* input, const char* units, float dpi, unsigned current_color)
{
NSVGparser* p;
NSVGimage* ret = 0;
- p = nsvg__createParser();
+ p = nsvg__createParser(current_color);
if (p == NULL) {
return NULL;
}
@@ -3124,7 +3127,7 @@ NSVGimage* nsvgParse(char* input, const char* units, float dpi)
return ret;
}
-NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi)
+NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi, unsigned current_color)
{
FILE* fp = NULL;
size_t size;
@@ -3141,7 +3144,7 @@ NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi)
if (fread(data, 1, size, fp) != size) goto error;
data[size] = '\0'; // Must be null terminated.
fclose(fp);
- image = nsvgParse(data, units, dpi);
+ image = nsvgParse(data, units, dpi, current_color);
free(data);
return image;
diff --git a/src/styleengine.cc b/src/styleengine.cc
index a2cb0c66..6aa99910 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -765,7 +765,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
a_Image_new(layout,
(void*)attrs->backgroundImage
->getMainImgRenderer(),
- 0xffffff);
+ 0xffffff, 0x000000);
// we use the pageUrl as requester to prevent cross
// domain requests as specified in domainrc
diff --git a/src/svg.c b/src/svg.c
index 98fe2ada..5536e9a3 100644
--- a/src/svg.c
+++ b/src/svg.c
@@ -31,6 +31,7 @@ typedef struct {
DilloUrl *url; /* Primary Key for the dicache */
int version; /* Secondary Key for the dicache */
int bgcolor; /* Parent widget background color */
+ int fgcolor; /* Parent widget foreground color */
} DilloSvg;
/*
@@ -71,9 +72,16 @@ static void Svg_write(DilloSvg *svg, void *Buf, uint_t BufSize)
if (strstr(Buf, "</svg>") == NULL)
return;
+ /* Use foreground as the current color, but transform to
+ * nanosvg color format (BGR). */
+ unsigned fg_r = (svg->fgcolor >> 16) & 0xff;
+ unsigned fg_g = (svg->fgcolor >> 8) & 0xff;
+ unsigned fg_b = (svg->fgcolor >> 0) & 0xff;
+ unsigned curcolor = NSVG_RGB(fg_r, fg_g, fg_b);
+
/* NULL-terminate Buf */
char *str = dStrndup(Buf, BufSize);
- NSVGimage *nimg = nsvgParse(str, "px", svg->Image->dpi);
+ NSVGimage *nimg = nsvgParse(str, "px", svg->Image->dpi, curcolor);
dFree(str);
if (nimg == NULL) {
@@ -149,6 +157,7 @@ void *a_Svg_new(DilloImage *Image, DilloUrl *url, int version)
svg->url = url;
svg->version = version;
svg->bgcolor = Image->bg_color;
+ svg->fgcolor = Image->fg_color;
return svg;
}