Skip to content

Instantly share code, notes, and snippets.

@codebrainz
Created February 7, 2012 09:52
Show Gist options
  • Select an option

  • Save codebrainz/1758842 to your computer and use it in GitHub Desktop.

Select an option

Save codebrainz/1758842 to your computer and use it in GitHub Desktop.
Scintilla GTK patch to add drop shadow below text
diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx
index 90f5c07..2206847 100644
--- a/scintilla/gtk/PlatGTK.cxx
+++ b/scintilla/gtk/PlatGTK.cxx
@@ -45,6 +45,8 @@
#define USE_CAIRO 1
+static double shadow_colour;
+
#ifdef USE_CAIRO
static cairo_surface_t *CreateSimilarSurface(GdkWindow *window, cairo_content_t content, int width, int height) {
@@ -764,6 +766,8 @@ class SurfaceImpl : public Surface {
Converter conv;
int characterSet;
void SetConverter(int characterSet_);
+ void PenShadowColour();
+ void SetShadowColorFromBack(ColourAllocated back, double shade);
public:
SurfaceImpl();
virtual ~SurfaceImpl();
@@ -1045,6 +1049,41 @@ void SurfaceImpl::PenColour(ColourAllocated fore) {
#endif
}
+// Call this whenever there's a new bg color before drawing text
+void SurfaceImpl::SetShadowColorFromBack(ColourAllocated back, double shade=0.1) {
+ // Skip (re)setting when default/black colour is used (FIXME)
+ if (back.AsLong() != 0) {
+ ColourDesired desired_colour(back.AsLong());
+
+ // Perform very simple conversion from RGB to grayscale
+ shadow_colour = (
+ desired_colour.GetRed() / 256.0 +
+ desired_colour.GetGreen() / 256.0 +
+ desired_colour.GetBlue() / 256.0) / 3.0;
+
+ // Lighten or darken depending on the background colour
+ //if (shadow_colour >= 0.5)
+ shadow_colour = shadow_colour - shade;
+ //else
+ // shadow_colour = shadow_colour + shade;
+
+ // Clamp between 0.0 and 1.0
+ if (shadow_colour < 0.0) shadow_colour = 0.0;
+ if (shadow_colour > 1.0) shadow_colour = 1.0;
+ }
+}
+
+void SurfaceImpl::PenShadowColour() {
+#ifdef USE_CAIRO
+ if (context) {
+ cairo_set_source_rgb(context,
+ shadow_colour,
+ shadow_colour,
+ shadow_colour);
+ }
+#endif
+}
+
int SurfaceImpl::LogPixelsY() {
return 72;
}
@@ -1618,6 +1657,10 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
PangoLayoutLine *pll = pango_layout_get_line(layout,0);
#endif
#ifdef USE_CAIRO
+ PenShadowColour();
+ cairo_move_to(context, xText+1, ybase+1);
+ pango_cairo_show_layout_line(context, pll);
+ PenColour(fore);
cairo_move_to(context, xText, ybase);
pango_cairo_show_layout_line(context, pll);
#else
@@ -1681,6 +1724,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len,
ColourAllocated fore, ColourAllocated back) {
FillRectangle(rc, back);
+ SetShadowColorFromBack(back);
DrawTextBase(rc, font_, ybase, s, len, fore);
}
@@ -1688,11 +1732,14 @@ void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const ch
void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len,
ColourAllocated fore, ColourAllocated back) {
FillRectangle(rc, back);
+ SetShadowColorFromBack(back);
DrawTextBase(rc, font_, ybase, s, len, fore);
}
void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len,
ColourAllocated fore) {
+ // Missing back parameter
+ // SetShadowColorFromBack(back);
// Avoid drawing spaces in transparent mode
for (int i=0;i<len;i++) {
if (s[i] != ' ') {
@elextr
Copy link
Copy Markdown

elextr commented Feb 7, 2012

Tried, on my system with my eyes it just looks blurry, and all colours look dark. I guess it depends on the resolution and brightness of the monitors, the font size etc.

Comment on the code, you shouldn't use a global for shadowcolour, there are several instances of Surface made by Editor.cxx, each should have its own shadowcolour since they are different backgrounds. Move line 48 to 768 and remove the static, no further change S/B needed.

@codebrainz
Copy link
Copy Markdown
Author

Hmm, seems to work here with a variety of font sizes and colours at my LCD's native resolution. It does look better though if the shadow is just always made darker even on dark backgrounds, like in the latest version of this Gist.

About the code, yeah, I pointed out in IRC it was garbage. Moving shadow_colour to the global scope from the class's scope is what finally made it actually work, since many Surfaces are created but not always getting the background colour set, this stores the background colour across Surfaces when it is set, which conveniently works fine in Geany since all Scintilla widgets always have the same background colour.

It's nothing I'd send upstream or even try to get into Geany, but alas I now have my drop shadowed text :)

@elextr
Copy link
Copy Markdown

elextr commented Feb 7, 2012 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment