diff options
author | Rodrigo Arias Mallo <rodarima@gmail.com> | 2024-07-27 12:52:51 +0200 |
---|---|---|
committer | Rodrigo Arias Mallo <rodarima@gmail.com> | 2024-07-27 12:54:47 +0200 |
commit | c2081d28740e03d43b9dbbe9dbd5ac6484e8953a (patch) | |
tree | eb1c8ac0965fee0139ee58db131a142b2150b4c8 /src | |
parent | 59b746f013f60050b91cb5f6f8dd4a96c47f380e (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.
Diffstat (limited to 'src')
-rw-r--r-- | src/dicache.c | 5 | ||||
-rw-r--r-- | src/html.cc | 5 | ||||
-rw-r--r-- | src/image.cc | 8 | ||||
-rw-r--r-- | src/image.hh | 6 | ||||
-rw-r--r-- | src/nanosvg.h | 21 | ||||
-rw-r--r-- | src/styleengine.cc | 2 | ||||
-rw-r--r-- | src/svg.c | 11 |
7 files changed, 39 insertions, 19 deletions
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 @@ -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; } |