aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/Xft1/xftdraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/lib/Xft1/xftdraw.c')
-rw-r--r--nx-X11/lib/Xft1/xftdraw.c482
1 files changed, 482 insertions, 0 deletions
diff --git a/nx-X11/lib/Xft1/xftdraw.c b/nx-X11/lib/Xft1/xftdraw.c
new file mode 100644
index 000000000..f9c3b8b79
--- /dev/null
+++ b/nx-X11/lib/Xft1/xftdraw.c
@@ -0,0 +1,482 @@
+/*
+ * $XFree86: xc/lib/Xft/xftdraw.c,v 1.15 2001/05/16 19:20:43 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "xftint.h"
+#include <X11/Xutil.h>
+
+XftDraw *
+XftDrawCreate (Display *dpy,
+ Drawable drawable,
+ Visual *visual,
+ Colormap colormap)
+{
+ XftDraw *draw;
+
+ draw = (XftDraw *) malloc (sizeof (XftDraw));
+ if (!draw)
+ return 0;
+ draw->dpy = dpy;
+ draw->drawable = drawable;
+ draw->visual = visual;
+ draw->colormap = colormap;
+ draw->core_set = False;
+ draw->render_set = False;
+ draw->render_able = False;
+ draw->clip = 0;
+ return draw;
+}
+
+XftDraw *
+XftDrawCreateBitmap (Display *dpy,
+ Pixmap bitmap)
+{
+ XftDraw *draw;
+
+ draw = (XftDraw *) malloc (sizeof (XftDraw));
+ if (!draw)
+ return 0;
+ draw->dpy = dpy;
+ draw->drawable = (Drawable) bitmap;
+ draw->visual = 0;
+ draw->colormap = 0;
+ draw->core_set = False;
+ draw->render_set = False;
+ draw->render_able = False;
+ draw->clip = 0;
+ return draw;
+}
+
+static XRenderPictFormat *
+_XftDrawFormat (XftDraw *draw)
+{
+ if (draw->visual == 0)
+ {
+ XRenderPictFormat pf;
+
+ pf.type = PictTypeDirect;
+ pf.depth = 1;
+ pf.direct.alpha = 0;
+ pf.direct.alphaMask = 1;
+ return XRenderFindFormat (draw->dpy,
+ (PictFormatType|
+ PictFormatDepth|
+ PictFormatAlpha|
+ PictFormatAlphaMask),
+ &pf,
+ 0);
+ }
+ else
+ return XRenderFindVisualFormat (draw->dpy, draw->visual);
+}
+
+static XRenderPictFormat *
+_XftDrawFgFormat (XftDraw *draw)
+{
+ XRenderPictFormat pf;
+
+ if (draw->visual == 0)
+ {
+ pf.type = PictTypeDirect;
+ pf.depth = 1;
+ pf.direct.alpha = 0;
+ pf.direct.alphaMask = 1;
+ return XRenderFindFormat (draw->dpy,
+ (PictFormatType|
+ PictFormatDepth|
+ PictFormatAlpha|
+ PictFormatAlphaMask),
+ &pf,
+ 0);
+ }
+ else
+ {
+ pf.type = PictTypeDirect;
+ pf.depth = 32;
+ pf.direct.redMask = 0xff;
+ pf.direct.greenMask = 0xff;
+ pf.direct.blueMask = 0xff;
+ pf.direct.alphaMask = 0xff;
+ return XRenderFindFormat (draw->dpy,
+ (PictFormatType|
+ PictFormatDepth|
+ PictFormatRedMask|
+ PictFormatGreenMask|
+ PictFormatBlueMask|
+ PictFormatAlphaMask),
+ &pf,
+ 0);
+ }
+}
+
+void
+XftDrawChange (XftDraw *draw,
+ Drawable drawable)
+{
+ draw->drawable = drawable;
+ if (draw->render_able)
+ {
+ XRenderPictFormat *format;
+
+ XRenderFreePicture (draw->dpy, draw->render.pict);
+ format = XRenderFindVisualFormat (draw->dpy, draw->visual);
+ draw->render.pict = XRenderCreatePicture (draw->dpy, draw->drawable,
+ format, 0, 0);
+ }
+}
+
+void
+XftDrawDestroy (XftDraw *draw)
+{
+ int n;
+
+ if (draw->render_able)
+ {
+ XRenderFreePicture (draw->dpy, draw->render.pict);
+ for (n = 0; n < XFT_DRAW_N_SRC; n++)
+ XRenderFreePicture (draw->dpy, draw->render.src[n].pict);
+ }
+ if (draw->core_set)
+ XFreeGC (draw->dpy, draw->core.draw_gc);
+ if (draw->clip)
+ XDestroyRegion (draw->clip);
+ free (draw);
+}
+
+Bool
+XftDrawRenderPrepare (XftDraw *draw,
+ XftColor *color,
+ XftFont *font,
+ int src)
+{
+ if (!draw->render_set)
+ {
+ XRenderPictFormat *format;
+ XRenderPictFormat *pix_format;
+ XRenderPictureAttributes pa;
+ int n;
+ Pixmap pix;
+
+ draw->render_set = True;
+ draw->render_able = False;
+ format = _XftDrawFormat (draw);
+ pix_format = _XftDrawFgFormat (draw);
+ if (format && pix_format)
+ {
+ draw->render_able = True;
+
+ draw->render.pict = XRenderCreatePicture (draw->dpy, draw->drawable,
+ format, 0, 0);
+ for (n = 0; n < XFT_DRAW_N_SRC; n++)
+ {
+ pix = XCreatePixmap (draw->dpy, draw->drawable,
+ 1, 1, pix_format->depth);
+ pa.repeat = True;
+ draw->render.src[n].pict = XRenderCreatePicture (draw->dpy,
+ pix,
+ pix_format,
+ CPRepeat, &pa);
+ XFreePixmap (draw->dpy, pix);
+
+ draw->render.src[n].color = color->color;
+ XRenderFillRectangle (draw->dpy, PictOpSrc,
+ draw->render.src[n].pict,
+ &color->color, 0, 0, 1, 1);
+ }
+ if (draw->clip)
+ XRenderSetPictureClipRegion (draw->dpy, draw->render.pict,
+ draw->clip);
+ }
+ }
+ if (!draw->render_able)
+ return False;
+ if (memcmp (&color->color, &draw->render.src[src].color,
+ sizeof (XRenderColor)))
+ {
+ if (_XftFontDebug () & XFT_DBG_DRAW)
+ {
+ printf ("Switching to color %04x,%04x,%04x,%04x\n",
+ color->color.alpha,
+ color->color.red,
+ color->color.green,
+ color->color.blue);
+ }
+ XRenderFillRectangle (draw->dpy, PictOpSrc,
+ draw->render.src[src].pict,
+ &color->color, 0, 0, 1, 1);
+ draw->render.src[src].color = color->color;
+ }
+ return True;
+}
+
+Bool
+XftDrawCorePrepare (XftDraw *draw,
+ XftColor *color,
+ XftFont *font)
+{
+
+ if (!draw->core_set)
+ {
+ XGCValues gcv;
+ unsigned long mask;
+ draw->core_set = True;
+
+ draw->core.fg = color->pixel;
+ gcv.foreground = draw->core.fg;
+ mask = GCForeground;
+ if (font)
+ {
+ draw->core.font = font->u.core.font->fid;
+ gcv.font = draw->core.font;
+ mask |= GCFont;
+ }
+ draw->core.draw_gc = XCreateGC (draw->dpy, draw->drawable,
+ mask, &gcv);
+ if (draw->clip)
+ XSetRegion (draw->dpy, draw->core.draw_gc, draw->clip);
+ }
+ if (draw->core.fg != color->pixel)
+ {
+ draw->core.fg = color->pixel;
+ XSetForeground (draw->dpy, draw->core.draw_gc, draw->core.fg);
+ }
+ if (font && draw->core.font != font->u.core.font->fid)
+ {
+ draw->core.font = font->u.core.font->fid;
+ XSetFont (draw->dpy, draw->core.draw_gc, draw->core.font);
+ }
+ return True;
+}
+
+void
+XftDrawString8 (XftDraw *draw,
+ XftColor *color,
+ XftFont *font,
+ int x,
+ int y,
+ XftChar8 *string,
+ int len)
+{
+ if (_XftFontDebug () & XFT_DBG_DRAW)
+ {
+ printf ("DrawString \"%*.*s\"\n", len, len, string);
+ }
+ if (font->core)
+ {
+ XftDrawCorePrepare (draw, color, font);
+ XDrawString (draw->dpy, draw->drawable, draw->core.draw_gc, x, y,
+ (char *) string, len);
+ }
+#ifdef FREETYPE2
+ else if (XftDrawRenderPrepare (draw, color, font, XFT_DRAW_SRC_TEXT))
+ {
+ XftRenderString8 (draw->dpy,
+ draw->render.src[XFT_DRAW_SRC_TEXT].pict,
+ font->u.ft.font,
+ draw->render.pict, 0, 0, x, y, string, len);
+ }
+#endif
+}
+
+#define N16LOCAL 256
+
+void
+XftDrawString16 (XftDraw *draw,
+ XftColor *color,
+ XftFont *font,
+ int x,
+ int y,
+ XftChar16 *string,
+ int len)
+{
+ if (font->core)
+ {
+ XChar2b *xc;
+ XChar2b xcloc[XFT_CORE_N16LOCAL];
+
+ XftDrawCorePrepare (draw, color, font);
+ xc = XftCoreConvert16 (string, len, xcloc);
+ XDrawString16 (draw->dpy, draw->drawable, draw->core.draw_gc, x, y,
+ xc, len);
+ if (xc != xcloc)
+ free (xc);
+ }
+#ifdef FREETYPE2
+ else if (XftDrawRenderPrepare (draw, color, font, XFT_DRAW_SRC_TEXT))
+ {
+ XftRenderString16 (draw->dpy,
+ draw->render.src[XFT_DRAW_SRC_TEXT].pict,
+ font->u.ft.font,
+ draw->render.pict, 0, 0, x, y, string, len);
+ }
+#endif
+}
+
+void
+XftDrawString32 (XftDraw *draw,
+ XftColor *color,
+ XftFont *font,
+ int x,
+ int y,
+ XftChar32 *string,
+ int len)
+{
+ if (font->core)
+ {
+ XChar2b *xc;
+ XChar2b xcloc[XFT_CORE_N16LOCAL];
+
+ XftDrawCorePrepare (draw, color, font);
+ xc = XftCoreConvert32 (string, len, xcloc);
+ XDrawString16 (draw->dpy, draw->drawable, draw->core.draw_gc, x, y,
+ xc, len);
+ if (xc != xcloc)
+ free (xc);
+ }
+#ifdef FREETYPE2
+ else if (XftDrawRenderPrepare (draw, color, font, XFT_DRAW_SRC_TEXT))
+ {
+ XftRenderString32 (draw->dpy,
+ draw->render.src[XFT_DRAW_SRC_TEXT].pict,
+ font->u.ft.font,
+ draw->render.pict, 0, 0, x, y, string, len);
+ }
+#endif
+}
+
+void
+XftDrawStringUtf8 (XftDraw *draw,
+ XftColor *color,
+ XftFont *font,
+ int x,
+ int y,
+ XftChar8 *string,
+ int len)
+{
+ if (font->core)
+ {
+ XChar2b *xc;
+ XChar2b xcloc[XFT_CORE_N16LOCAL];
+ int n;
+
+ XftDrawCorePrepare (draw, color, font);
+ xc = XftCoreConvertUtf8 (string, len, xcloc, &n);
+ if (xc)
+ {
+ XDrawString16 (draw->dpy, draw->drawable, draw->core.draw_gc, x, y,
+ xc, n);
+ }
+ if (xc != xcloc)
+ free (xc);
+ }
+#ifdef FREETYPE2
+ else if (XftDrawRenderPrepare (draw, color, font, XFT_DRAW_SRC_TEXT))
+ {
+ XftRenderStringUtf8 (draw->dpy,
+ draw->render.src[XFT_DRAW_SRC_TEXT].pict,
+ font->u.ft.font,
+ draw->render.pict, 0, 0, x, y, string, len);
+ }
+#endif
+}
+
+
+void
+XftDrawRect (XftDraw *draw,
+ XftColor *color,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ if (XftDrawRenderPrepare (draw, color, 0, XFT_DRAW_SRC_RECT))
+ {
+ XRenderFillRectangle (draw->dpy, PictOpOver, draw->render.pict,
+ &color->color, x, y, width, height);
+ }
+ else
+ {
+ XftDrawCorePrepare (draw, color, 0);
+ XFillRectangle (draw->dpy, draw->drawable, draw->core.draw_gc,
+ x, y, width, height);
+ }
+}
+
+Bool
+XftDrawSetClip (XftDraw *draw,
+ Region r)
+{
+ Region n = 0;
+
+ if (!r && !draw->clip)
+ return True;
+
+ if (r)
+ {
+ n = XCreateRegion ();
+ if (n)
+ {
+ if (!XUnionRegion (n, r, n))
+ {
+ XDestroyRegion (n);
+ return False;
+ }
+ }
+ }
+ if (draw->clip)
+ {
+ XDestroyRegion (draw->clip);
+ }
+ draw->clip = n;
+ if (draw->render_able)
+ {
+ XRenderPictureAttributes pa;
+ if (n)
+ {
+ XRenderSetPictureClipRegion (draw->dpy, draw->render.pict, n);
+ }
+ else
+ {
+ pa.clip_mask = None;
+ XRenderChangePicture (draw->dpy, draw->render.pict,
+ CPClipMask, &pa);
+ }
+ }
+ if (draw->core_set)
+ {
+ XGCValues gv;
+
+ if (n)
+ XSetRegion (draw->dpy, draw->core.draw_gc, n);
+ else
+ {
+ gv.clip_mask = None;
+ XChangeGC (draw->dpy, draw->core.draw_gc,
+ GCClipMask, &gv);
+ }
+ }
+ return True;
+}